跨程序集边界返回/使用动态匿名类型

fri*_*ism 25 .net c# dynamic anonymous-types

下面的代码效果很好.如果GetUse方法在不同的程序集中,则代码将失败并出现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 };
    }
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 34

使用ExpandoObject而不是匿名类型.这应该允许您安全地跨越装配边界:

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

    return person;
}
Run Code Online (Sandbox Code Playgroud)

通常,匿名类型实际上只应在生成它们的同一方法中使用.一般来说,从方法中返回匿名类型会导致比它解决的问题更多的问题.


jpb*_*chi 8

问题的原因是匿名类型是程序集内部的.这就是动态语言运行时不允许您访问其他程序集的属性的原因.

一个解决方案是在这个解释.您可以在程序集中放置一个自定义属性,该属性定义匿名类型,允许其他程序集访问其内部.

另一种解决方案是返回公共类的对象(具有公共属性).当然,这会破坏匿名类型的优势.

第三种解决方案是使用Reed Copsey建议的ExpandoObject.

如果您仍想使用匿名类型,则可以编写一个动态类来"装饰"任何匿名类型并公开其成员.这样的类必须实现IDynamicMetaObjectProvider接口并通过反射访问装饰对象.可能这个东西已经被那里的人实现了.