在不知道其泛型类型的情况下将对象添加到集合

时间:2013-03-16 17:21:44

标签: c# generics collections interface

class Program
{
    public static void Main(string[] args)
    {
        List<MyInterface> myList = new List<MyInterface>();

        myList.Add(new MyClass<int>());

        foreach (MyInterface item in myList)
        {
            (MyClass)item).Foo(); // <---- Critical Line
        }
    }
}

interface MyInterface { }

class MyClass<T> : MyInterface
{
    public MyClass() { }
    public void Foo() { DoSomething(); }
}

我想在不知道对象的excact(generic)类型的情况下使用Foo()的{​​{1}}方法。有没有办法打电话呢?我会在编译代码时知道MyClass,所以我可以将它存储在通过T实现的属性中吗?

感谢您的帮助!

修改:抱歉不清楚;还有其他类实现InterfaceB,我正在检查项目类型是否为ClassB,因此我无法将MyInterface放入Foo()

4 个答案:

答案 0 :(得分:2)

为了静态引用ClassB<T>,您需要在代码中指定泛型参数。您不能使用名称ClassB,因为它将引用名为ClassB的非泛型类。

另一种方法是将所需信息添加到InterfaceB,因为它不需要通用参数

interface InterfaceB 
{
  InterfaceA FooUntyped();
}

...

foreach (InterfaceB item in bList) {
  aList.Add(item.FooUntyped());
}

答案 1 :(得分:1)

interface MyInterface { }
interface MyFooInterface<T>
{
    List<T> Foo<T>();
}

class MyClass<T> : MyInterface, MyFooInterface<T>
{
    public MyClass() { }
    public List<T> Foo<T>() { DoSomething(); }
}

class MyClassB<T> : MyInfterface
{...}

...
        foreach (MyFooInterface item in myList.OfType<MyFooInterface>)
        {
            item.Foo();
        }
...

答案 2 :(得分:1)

关键的见解是,MyClass<int>MyClass<SomethingElse>是100%无关的类型,因此您不能将它们视为相同。甚至不是部分的。就像你在编译器中写了T1T2一样。

因此,您必须创建公共基类/接口或使用dynamic

答案 3 :(得分:-3)

你不是在迭代ClassB的项目,而是迭代实际上没有指定Foo方法的interfaceB。

但不检查:

var itemB = item as ClassB; if (itemB != null){ itemB.Foo() }