2017-01-19 4 views
0

Скажем, у меня есть код, который выглядит следующим образом:Как я могу получить доступ к полю анонимного типа, хранящегося в переменной объекта?

public struct Foo 
    { 
     public object obj; 
     public Foo(int val) 
     { 
      obj = new { 
       bar = val 
      }; 
      Console.WriteLine(obj.bar); // Can't access bar. 
     } 
    } 

Обычно я вижу анонимные типы хранимых в неявно типизированных переменных и их поля могут быть доступны только штраф в этом случае. Но я не могу неявно вводить var в этом случае, потому что obj - это поле в структуре и, по-видимому, не может быть инициализировано. Итак, как мне получить доступ к полю bar?

+0

Когда структура получила конструктор по умолчанию? LOL – ViVi

+0

Что это значит? Вы говорите, что он не должен компилироваться, не предоставляя структуре явно определенный конструктор без параметров? Потому что он компилируется без него. –

ответ

2

dynamic Используйте ключевое слово:

public struct Foo 
{ 
    public dynamic obj; 
    public Foo(int val) 
    { 
     obj = new 
     { 
      bar = val 
     }; 
     Console.WriteLine(obj.bar); // is accessible now 
    } 
} 
2

То, что вы делаете не будет компилироваться, так как object не имеет определения для bar. Если по какой-либо причине вам необходимо удержать ссылку на анонимный тип, вам нужно будет использовать dynamic. Обратите внимание, что у вас не будет безопасности типа компиляции, и для этого может быть незначительный удар по производительности.

public struct Foo 
{ 
    public dynamic obj; 
    public Foo(int val) 
    { 
     obj = new { 
      bar = val 
     }; 
    } 

    public void WriteMyFooBar() 
    { 
     Console.WriteLine(obj.bar); 
    } 
} 

Однако, один делает вопрос использования анонимного типа здесь вместо определения интерфейса, который обеспечивает, по меньшей мере, поглотитель для bar.

2

Либо Вы можете попробовать литье obj объекта типа к dynamic, а затем получить доступ к требуемой величине, или вы можете изменить тип obj к dynamic.

Попробуйте это:

Console.WriteLine(((dynamic)obj).bar)); 
1

Вы можете использовать dynamic, как другие предложили или вы можете пользователю "прототип" метод, как это:

public struct Foo 
{ 
    public object obj; 
    public Foo(int val) 
    { 
     obj = new { 
      bar = val 
     }; 
     this.Use(new { bar = 0 }, x => Console.WriteLine(x.bar)); 
    } 
    public void Use<T>(T prototype, Action<T> action) 
    { 
     action((T)this.obj); 
    } 
} 

Это работает просто отлично.

Смежные вопросы