我有一种在运行时(通过编码的编译)创建的类型,并实现已知的(在编译时间)接口。

假设接口是 IMyInterface, ,我有类型的实例 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 类型,我添加了一个公共静态方法,该方法返回该类型的实例。然后,在编译了此类型后,我获得了此方法的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 输入此类实例,我可以做

Func<IMyInterface> createObject = ( Func<IMyInterface> )(
    Delegate.CreateDelegate(typeof(Func<IMyInterface>),
                            myType.GetMethod("__Instantiator")) );

IMyInterface obj = createObject(); // This will call MyClass.__Instantiator()
有帮助吗?

解决方案

您可以编译简单的Lambda表达式以获得您的委托。

var del = Expression.Lambda<Func<IMyInterface>>(Expression.New(type)).Compile();

其他提示

您可以使用 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 );
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top