【问题标题】:Creating a generic IList instance using reflection使用反射创建通用 IList 实例
【发布时间】:2010-11-12 17:21:16
【问题描述】:

我正在尝试使用反射创建一个通用的对象列表。下面的代码抛出一个错误 Cannot create an instance of an interface. 。我可以将 IList 更改为 List 并且它工作正常,但我想知道是否有办法让它与 IList 一起工作。

    var name = typeof (IList<T>).AssemblyQualifiedName;

    Type type = Type.GetType(name);

    var list = Activator.CreateInstance(type);

【问题讨论】:

  • typeof (IList) 返回与第二行中的表达式相同的类型 (Type.GetType(name);) 换句话说,只需在需要时执行 var type = typeof(sometype)该特定类型的 System.Type 对象

标签: c# asp.net reflection


【解决方案1】:

不,不能创建接口的实例。

.NET(或者更确切地说是 Activator.CreateInstance 方法)应该如何决定它应该实例化该接口的哪个实现?

你不能这样做:

IList<int> l = new IList<int>();

要么,你可以吗? 你不能实例化一个接口,因为接口只是一个定义或契约,描述了一个类型应该实现的功能。

【讨论】:

    【解决方案2】:

    你必须实例化一个具体的类,所以如果你这样做

    var type = Type.GetType(typeof (List<T>).AssemblyQualifiedName);
    var list = (Ilist<T>)Activator.CreateInstance(type);
    

    您将成功(当然,只要您为 T 提供有效值)。

    【讨论】:

    • 你不能这样做:var list=(IList)Activator.CreateInstance(typeof(List)); ???
    • 是的,你可以,我走了很长的路让它更接近 OPs sn-p
    【解决方案3】:

    Activator.CreateInstance 方法调用默认构造函数来创建作为参数传递的类型的实例。这个类型必须是非抽象的,没有接口,并且有一个默认的构造函数,这个函数才能成功。

    【讨论】:

      【解决方案4】:

      我认为你不能让它工作,因为你不知道你需要创建什么类型的对象。

      抽象类也会有同样的问题。

      【讨论】:

        【解决方案5】:

        不,那是不可能的。错误信息非常清楚。您不能创建接口的实例。

        它如何知道您想要一个实例的特定类?通常,许多类实现相同的接口。它应该随机选择一个吗? ;-)

        这与反射无关,因为您也无法正常“实例化”接口。只分配实现接口的对象,然后传递接口引用。

        【讨论】:

          【解决方案6】:

          显然你不能直接实例化IList&lt;T&gt; 类型的对象,因为它是一个接口类型。

          您应该尝试实例化 List&lt;T&gt;,然后将其返回为 IList&lt;T&gt;

          【讨论】:

            【解决方案7】:
            IList<T> Create<T>()
            {
                Type baseListType = typeof(List<>);
                Type listType = baseListType.MakeGenericType(typeof(T));
                 return Activator.CreateInstance(listType) as IList<T>;
            }
            

            【讨论】:

            • 你的 sn-p 有问题。 typeof(int) 应该是 typeof(T)。您应该尝试编译并运行它。我没有,但我不需要告诉它是错误的。修复它,我修复投票。 ;-)
            【解决方案8】:

            嗯,你可以在 C# 中实例化一个接口。但前提是你真的告诉它怎么做。

            看看http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.coclassattribute.aspxhttp://blogs.msdn.com/brada/archive/2004/10/10/240523.aspx

            但是,在您的情况下,您似乎误解了接口的工作原理。

            只需创建一个列表,然后返回一个 IList,您的调用代码就不会关心您是否实际使用了一个 List

            【讨论】:

              猜你喜欢
              • 2018-03-29
              • 2016-04-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-10
              • 2011-09-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多