【问题标题】:Adding generic object to generic list in C#在 C# 中将泛型对象添加到泛型列表
【发布时间】:2010-10-19 18:05:47
【问题描述】:

我有相关部分看起来像的课程

class C {
    void Method<T>(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<?> list = new List<?>();
}

我应该如何定义列表以便类编译?

我想要一个List&lt;SomeClass&lt;?&gt;&gt; 类型的列表,即SomeClass 的对象列表,其中每个对象都可以有任何类型参数。 Java ? 结构允许这样做;什么是 C# 等价物?如果不存在这样的事情,是否有合适的解决方法? (List&lt;object&gt; 可以,但非常丑陋。)

【问题讨论】:

  • 您能否详细说明您希望通过“方法”功能添加的项目类型?
  • 啊,没关系,我在评论中看到了。
  • 在 c# 4.0 中,您可以将 SomeClass 声明为动态而不使用泛型。然后列表变为 List.

标签: c# generics list


【解决方案1】:

我认为您不能在 C# 中执行此操作...您必须将类型参数添加到类中:

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<SomeClass<T>> list = new List<SomeClass<T>>();
}

另一种选择是使用接口:

class C {

    void Method<T>(T obj)
         where T : ISomeClass {
        list.Add(obj);
    }
    List<ISomeClass> list = new List<ISomeClass>();
}

【讨论】:

  • 我认为这更符合我理解提问者要问的精神(界面版本)。基本上它是“部分已知”项目的列表,但不仅仅是“List
  • 感谢您的帮助。所以stackoverflow让我编辑我的问题......但是有没有办法将你的答案与下面的答案结合起来,添加关于我在C#中不可能实现的额外信息?
  • @errcw 我可以编辑它,或者其他任何拥有 2k+ 代表的人都可以...你想要什么具体信息?
  • Mehrdad 关于 C# 3/4 的简单技术说明:“不幸的是,在 C# 3.0 中没有直接的等价物,因为泛型是不变的。你将能够以优雅的方式做这样的事情使用 C# 4.0 安全协/逆变功能。”
【解决方案2】:

不幸的是,C# 3.0 中没有直接的等价物,因为泛型是不变的。 您将能够使用 C# 4.0 安全协/逆变功能以优雅的方式执行此类操作。 要解决此问题,您可以从非泛型基类继承 SomeClass&lt;T&gt;,并改为创建 List&lt;BaseClass&gt;。 如果类的每个实例应该只包含一种类型,则可以将类本身设为泛型并在那里设置类型参数。

【讨论】:

  • 感谢 BaseClass 提示,当您想模拟 Java 通配符时确实非常有用。
【解决方案3】:

要做你想做的事,你有两个选择。

您可以使用 List,并处理对象。这将不是类型安全的,并且会对值类型产生装箱/拆箱问题,但它会起作用。

您的另一个选择是使用通用约束来限制基类或接口,并使用 List

【讨论】:

    【解决方案4】:

    我对 Java 的 ? 构造一无所知,但我认为以下内容最接近地保留了您现有的语法,同时也符合您的描述。

        class SomeClass<T>
        {
        }
    
        class C
        {
            void Add<T>(SomeClass<T> item)
            {
                Type type = typeof(SomeClass<T>);
                if (!list.ContainsKey(type))
                    list[type] = new List<SomeClass<T>>();
                var l = (List<SomeClass<T>>)list[type];
                l.Add(item);
            }
    
            public void Method<T>(SomeClass<T> obj)
            {
                Add(obj);
            }
            readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
        }
    

    使用以下方法对其进行测试:

        class Program
        {
            static void Main(string[] args)
            {
                var c = new C();
                var sc1 = new SomeClass<int>();
                var sc2 = new SomeClass<String>();
                c.Method(sc1);
                c.Method(sc2);
                c.Method(sc1);
                c.Method(sc2);
            }
        }
    

    【讨论】:

      【解决方案5】:

      就个人而言,我会在可能的情况下这样做;将泛型参数从方法中移到类中。

      class C<T> {
          void Method(SomeClass<T> obj) {
              list.Add(obj);
          }
          List<?> list = new List<?>();
      }
      

      如果您的通用列表是一个成员,那么在构造类时应该考虑到这一点。如果没有更多的类使用上下文,我们很难建议最好的模式。

      【讨论】:

        猜你喜欢
        • 2019-07-01
        • 2016-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多