调用非泛型方法(Generic <Base> [] args)并传递Generic <Derived>数组?

Kev*_*ice 0 c# c#-4.0

调用非泛型方法并使用不同泛型类型传递泛型参数的解决方案?

我想象中的梦想:

void FooBulous(Foo<object>[] fooArray) {  } // Accept any 'Foo<BaseType>'

var fooArray = new Foo<object>[]    // Array of 'Foo<BaseType>'
{
  new Foo<Cat>(),
  new Foo<Dog>(),
};

FooBulous(fooArray); // Pass the 'Foo<BaseType>[]' array
Run Code Online (Sandbox Code Playgroud)

我的现实:

void BarBaric(object[] barArray) {  } // Can't constrain to 'Foo<>'

var barArray = new object[]  // Same problem
{
  new Bar<Cat>(),
  new Bar<Dog>(),
};

BarBaric(barArray); // Barbaric! I thought the 'void *ptr' days were over!
Run Code Online (Sandbox Code Playgroud)

综上所述:

void Fee(object[] params)      { /* WORKS! But not constrained to 'Foo<Base>' */ }
void Fie(Foo<Cat>[] params)    { /* Does not accept 'Foo<Dog>' */ }
void Foe(Foo<>[] params)       { /* ERROR: 'Type expected' */ }
void Fum(Foo<object>[] params) { /* Cannot convert 'Foo<Cat>' to 'Foo<object>' */ }
Run Code Online (Sandbox Code Playgroud)

显然,这是不可能的......有一个干净的选择吗?

Jon*_*eet 5

问题是a Foo<Cat>不是a Foo<object>.假设Foo看起来像这样:

public class Foo<T>
{
    public void Method(T input)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,Foo<Cat>总是期待Cat的值input参数Method.但是,如果你可以Foo<Cat>像对待一样Foo<object>:

Foo<Cat> catFoo = new Foo<Cat>();
Foo<object> objectFoo = catFoo;
objectFoo.Method(new object()); // Eek! Type safety is broken!
Run Code Online (Sandbox Code Playgroud)

现在,通用方差在.NET 4(和C#4)中可用,但适用于接口和委托,并且适用于那些使用类型参数声明out并且in在类型参数声明处适当的装饰.这可能对你有用,也可能没用.

另一种选择是Foo<T>从抽象的非泛型基类派生,该基类Foo提供与之无关的所有成员T.然后你可以写:

void Foobulous(Foo[] fooArray)

...

Foobulous(new Foo[] {
    new Foo<object>(),
    new Foo<Cat>(),
    new Foo<Dog>()
});
Run Code Online (Sandbox Code Playgroud)

一切都会好的,只要Foobulous不需要使用任何依赖的方法T- 它本不应该,因为它可以Foo采用不同类型参数的值.