在C#中通过反射创建匿名对象

时间:2020-03-06 14:31:55  来源:igfitidea点击:

有什么方法可以在.NET 3.5的运行时通过反射创建C3.0匿名对象?我想在我的序列化方案中支持它们,所以我需要一种以编程方式操纵它们的方法。

稍后进行编辑以阐明用例

一个额外的约束是,我将在Silverlight应用程序中运行所有代码,因此额外的运行时不是一个选择,并且不确定如何动态生成代码。

解决方案

使用反射获取Type,在类型上使用GetConstructor,在构造函数上使用Invoke。

编辑:感谢Sklivvz指出我回答了一个未被询问的问题;)

实际问题的答案:我发现生成Ccode,然后使用CodeDomProvider(而不是CodeDOM本身,这很糟糕),然后对其进行向下编译并反映出其中的类型,这是在运行时执行"匿名"对象的最简单方法。

我们可能需要研究DLR。我自己还没有这样做(但是),但DLR(动态语言)的用例听起来很像我们要执行的操作。

根据我们要执行的操作,Castle框架的动态代理对象也可能很合适。

就在这里。
从记忆里:

public static T create<T>(T t)
{
    return Activator.CreateInstance<T>();
}

object anon = create(existingAnonymousType);

我们可以使用Reflection.Emit动态生成所需的类,尽管编写代码很麻烦。

如果我们决定采用这种方法,建议我们下载适用于.NET Reflector的Reflection Emit语言插件,因为它使我们能够了解如何使用Reflection.Emit构建现有的类,因此是学习框架这一方面的好方法。

我们可能还需要看一下FormatterServices类:FormatterServices上的MSDN条目

它包含将创建类的空实例的GetSafeUninitializedObject以及进行序列化时的其他一些便捷方法。

在回应迈克尔的评论时:
如果我们没有类型T的Type实例,则始终可以从typeof(T)中获取它。如果我们有一个未知类型的对象,则可以在其上调用GetType()以获得Type实例。

这是另一种方式,似乎更直接。

object anon = Activator.CreateInstance(existingObject.GetType());