Возвратитесь/используйте динамический анонимный тип через границы блока

Код ниже работает отлично. Если Get и Use методы находятся в различных блоках, сбоях кода с RuntimeBinderException. Это вызвано тем, что система времени выполнения .NET только гарантирует общность анонимных типов (<string, int> в этом случае) в рамках блоков.

Там какой-либо путь состоит в том, чтобы одурачить систему во время выполнения для преодоления этого? Я могу осмотреть объект в отладчике на Use сторона и отладчик видят соответствующие свойства.

class Program
{
    static void Main(string[] args)
    {
        UsePerson();
        Console.ReadLine();
    }

    public static void UsePerson()
    {
        var person = GetPerson();

        Console.WriteLine(person.Name);
    }

    public static dynamic GetPerson()
    {
        return new { Name = "Foo", Age = 30 };
    }
}
25
задан friism 8 January 2011 в 03:55
поделиться

3 ответа

Используйте ExpandoObject вместо анонимного типа. Это должно позволить вам безопасно пересекать границы сборки:

public static dynamic GetPerson()
{
    dynamic person = new ExpandoObject();
    person.Name = "Foo";
    person.Age = 30;

    return person;
}

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

34
ответ дан 28 November 2019 в 21:05
поделиться

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

Одно решение объясняется в этом сообщении . Вы можете поместить в сборку настраиваемый атрибут, определяющий анонимный тип, позволяющий другой сборке получить доступ к своим внутренним компонентам.

Другое решение - возврат объекта открытого класса (с общедоступными свойствами). Это, конечно, убьет преимущества анонимного типа.

Третье решение - использовать ExpandoObject , как было предложено Ридом Копси .

Если вы все еще хотите использовать анонимный тип, вы можете написать динамический класс, который «украшает» любой анонимный тип и предоставляет его члены. Такой класс должен реализовать интерфейс IDynamicMetaObjectProvider и обращаться к декорированному объекту через отражение. Возможно, это уже кто-то реализовал.

8
ответ дан 28 November 2019 в 21:05
поделиться

Другим хорошим решением может быть использование кортежей, которые были введены в .Net 4: http://msdn.microsoft.com/en-us/library/dd268536.aspx

1
ответ дан 28 November 2019 в 21:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: