繁体   English   中英

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

[英]Add an object to a collection without knowing its generic type

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(泛型)类型的情况下使用MyClassFoo()方法。 有没有办法打电话呢? 编译代码时我会知道T ,所以我是否可以将它存储在通过InterfaceB实现的属性中?

谢谢你的帮助!

编辑:抱歉不清楚; 还有其他类实现MyInterface ,我正在检查项目的类型是ClassB,所以我不能把Foo()放到MyInterface

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

实现此功能的另一种方法是将所需信息添加到InterfaceB因为它不需要通用参数

interface InterfaceB 
{
  InterfaceA FooUntyped();
}

...

foreach (InterfaceB item in bList) {
  aList.Add(item.FooUntyped());
}
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();
        }
...

关键的见解是MyClass<int>MyClass<SomethingElse>是100%无关的类型,所以你不能对它们进行相同的处理。 甚至不是部分的。 就像你把T1T2写入编译器一样。

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

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

但是没有检查:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM