有没有办法在 .NET 3.5 中通过反射在运行时创建 C# 3.0 匿名对象?我想在我的序列化方案中支持它们,所以我需要一种以编程方式操作它们的方法。
稍后编辑以阐明用例
一个额外的限制是我将在 Silverlight 应用程序中运行所有这些,因此额外的运行时不是一个选项,并且不确定动态生成代码将如何工作。
有没有办法在 .NET 3.5 中通过反射在运行时创建 C# 3.0 匿名对象?我想在我的序列化方案中支持它们,所以我需要一种以编程方式操作它们的方法。
稍后编辑以阐明用例
一个额外的限制是我将在 Silverlight 应用程序中运行所有这些,因此额外的运行时不是一个选项,并且不确定动态生成代码将如何工作。
就在这里。从记忆里:
public static T create<T>(T t)
{
return Activator.CreateInstance<T>();
}
object anon = create(existingAnonymousType);
这是另一种方式,似乎更直接。
object anon = Activator.CreateInstance(existingObject.GetType());
使用反射获取类型,对类型使用 GetConstructor,对构造函数使用 Invoke。
编辑:感谢 Sklivvz 指出我回答了一个没有被问到的问题;)
实际问题的答案:我发现生成 C# 代码,然后使用 CodeDomProvider(但不是 CodeDOM 本身 - 太糟糕了),然后将其编译下来并从中反映类型是执行“匿名”对象的最简单方法运行。
您可能想查看 DLR。我自己(还)还没有这样做,但是 DLR(动态语言)的用例听起来很像您正在尝试做的事情。
根据您想要做什么,Castle 框架的动态代理对象也可能很合适。
您可以使用 Reflection.Emit 动态生成所需的类,尽管编写代码非常讨厌。
如果您决定采用这条路线,我建议您下载适用于.NET Reflector的Reflection Emit Language Addin,因为这可以让您了解如何使用 Reflection.Emit 构建现有类,因此是学习框架这一角落的好方法。
您可能还想查看 FormatterServices 类:MSDN entry on FormatterServices
它包含将创建该类的空实例的 GetSafeUninitializedObject 以及在进行序列化时的其他几个方便的方法。
回复 Michael 的评论:如果您没有类型 T 的 Type 实例,您始终可以从 typeof(T) 获取它。如果您有一个未知类型的对象,您可以在其上调用 GetType() 以获取 Type 实例。