首页 > 解决方案 > 激活器创建通用实例

问题描述

我注意到使用接口列表作为构造函数参数的泛型类有一个奇怪的行为。

假设我们有以下课程

public class GenericClass<T> where T : IInterface
{
    public GenericClass(int inInt, List<T> inList){
    }

    public GenericClass(int inInt, object inObject){
    }
}

当我尝试创建这样的实例时(tmpType 实现IInterface):

IEnumerable<IInterface> tmpSomeObjects = xy;

Activator.CreateInstance(typeof(GenericClass<>).MakeGenericType(tmpType), 5, (List<IInterface>)tmpSomeObjects);

第二个构造函数将被调用 (int, object)。

我可能错过了一个重要的点......我希望第一个构造函数被执行。

标签: c#generics

解决方案


IEnumerable是 type IEnumerable<IInterface>,但是您正在构造的类型具有派生类型的泛型参数,因此它与确切的构造函数不匹配。

TFoo(实现IInterface),你的类型变成:

public class GenericClass<Foo>
{
    public GenericClass(int inInt, List<Foo> inList){
    }

    public GenericClass(int inInt, object inObject){
    }
}

然而,您将IEnumerable<IInterface>(or List<IInterface>) 传递给它,它不匹配List<Foo>,所以这就是它更喜欢的原因object(不仅它是首选......另一个构造函数根本不匹配)。

试试看:删除构造函数object并尝试这样做:

var list = new List<IInterface>();
var x = new GenericClass<TypeImplementingIInterface>(5, list);

那甚至不会编译。

所以在你的情况下的解决方案很简单......在构造函数中制作参数IEnumerable<IInterface>,而不是List<T>你真正想要传递的参数


推荐阅读