【发布时间】:2013-12-19 15:15:21
【问题描述】:
我有一个在运行时创建的类型(通过从 CodeDOM 编译)并实现一个已知的(在编译时)接口。
假设接口是IMyInterface,我有一个类型实例Type myType,它是从我刚刚从CodeDOM 编译的程序集中获得的。 myType代表的类实现了IMyInterface。
我想获得一个委托Func<IMyInterface>,它在被调用时将返回一个myType 的实例。
我想这样称呼:
Func<IMyInterface> createObject = GetObjectCreator<IMyInterface>(myType);
IMyInterface myObject = createObject();
我知道,如果我有一个 MethodInfo m 用于返回 myType 对象实例的无参数方法,那么我可以这样做:
Func<IMyInterface> createObject =
( Func<IMyInterface> )Delegate.CreateDelegate(typeof(Func<IMyInterface>), m);
但是如果我没有这样的方法,而我唯一拥有的就是该类型的无参构造函数,那我该如何获取这个委托呢?
更新
虽然 fsimonazzi 的回答完全符合我的要求,但我的方法有点不同。
因为我控制了myType 类型的创建和编译,所以我添加了一个返回该类型实例的公共静态方法。然后,在编译完这个类型之后,我得到了这个方法的 MethodInfo 实例,并调用了 Delegate.CreateDelegate 创建了所需的委托。
CodeTypeDeclaration type = new CodeTypeDeclaration
{
Name = "MyClass",
IsClass = true,
TypeAttributes = TypeAttributes.Public
};
type.BaseTypes.Add(new CodeTypeReference(typeof(IMyInterface)));
// fullName is the full name of the myType (including namespace)
var staticInstantiator = new CodeMemberMethod
{
Name = "__Instantiator",
ReturnType = new CodeTypeReference("MyNamespace.MyClass"),
Attributes = MemberAttributes.Public | MemberAttributes.Static
};
staticInstantiator.Statements.Add(
new CodeMethodReturnStatement(
new CodeObjectCreateExpression("MyNamespace.MyClass")));
type.Members.Add(staticInstantiator);
以上代码生成此代码并放入类声明中
public static MyNamespace.MyClass __Instantiator()
{
return new MyNamespace.MyClass();
}
现在编译这段代码并为这个类创建一个myType Type 实例,我可以这样做
Func<IMyInterface> createObject = ( Func<IMyInterface> )(
Delegate.CreateDelegate(typeof(Func<IMyInterface>),
myType.GetMethod("__Instantiator")) );
IMyInterface obj = createObject(); // This will call MyClass.__Instantiator()
【问题讨论】:
-
您忘记实际创建对象,调用 Activator.CreateInstance()。
-
重点是不要使用这种技术。 GetObjectCreator 应该为我创建实例的方法返回一个委托。如果需要,可以在运行时编译该方法,但我不想每次需要实例时都调用 Activator.CreateInstance()。
-
你最好考虑一下。单例是一个名字很漂亮的错误。
-
谁谈过单身?我只会得到一个委托,我可以调用它一百万次,得到一百万个“myType”实例
-
你不明白我的要求。方法“IMyInterface Create(){ return new myType(); }”只是一种方法,但每次调用都会返回一个新实例。整个问题是我没有这个方法,而且我在编译时不知道“myType”,所以我想在运行时创建它。看看 fsimonazzi 的回答。
标签: c# dynamic reflection code-generation codedom