我有一个在运行时创建的类型(通过CodeDOM编译)并实现一个已知的(在编译时)接口。
假设接口是IMyInterface
,并且我从我刚刚从CodeDOM编译的程序集中获取了Type实例Type myType
。 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
Type的创建和编译,我添加了一个返回该类型实例的公共静态方法。然后,在编译此类型之后,我为此方法获得了一个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()
答案 0 :(得分:3)
您可以编译一个简单的lambda表达式来获取您的委托。
var del = Expression.Lambda<Func<IMyInterface>>(Expression.New(type)).Compile();
答案 1 :(得分:0)
您可以使用Activator.CreateInstance( type )
来实际创建您的类型的实例。如果你想在Func<IMyInterface>
填充它,那么你可以将它包装在lambda中:
Func<IMyInterface> createObject = () => (IMyInterface) Activator.CreateInstance( myType );
IMyInterface myObject = createObject();
更新:
由于Activator.CreateInstance
显然不是你想要的(尽管我不完全确定原因),我想你可以使用反射来找到该类型的无参数构造函数:
public Func<T> GetObjectCreator<T>( Type type )
{
// I'd probably add additional checks here to see that the
// conversion to T is actually possible.
var ctor = type.GetConstructor( Type.EmptyTypes );
if( ctor == null ) throw new ArgumentException( "type", "Public parameterless constructor not found." )
return () => (T) ctor.Invoke( null );
}