调用非泛型方法(Generic[] args)并传递Generic数组

本文关键字:Generic 数组 args Derived 泛型方法 Base 调用 | 更新日期: 2023-09-27 18:01:42

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

My imaginary dream:

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

我的现实:

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!
在简介:

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>' */ }

显然,这是不可能的…有干净的替代品吗?

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

问题是Foo<Cat>不是Foo<object>。假设Foo是这样的:

public class Foo<T>
{
    public void Method(T input)
    {
        ...
    }
}

那么Foo<Cat>总是期望input参数到MethodCat值。但是如果你可以把Foo<Cat>当作Foo<object>,你可以这样做:

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

现在泛型方差在。net 4(和c# 4)中是可用的,但是只能用于接口和委托,而只能用于在类型参数声明点用outin适当修饰的。这对你可能有用,也可能没用。

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

void Foobulous(Foo[] fooArray)
...
Foobulous(new Foo[] {
    new Foo<object>(),
    new Foo<Cat>(),
    new Foo<Dog>()
});
只要Foobulous不需要使用任何依赖于T的方法——它不应该这样做,因为它可以使用不同类型参数的Foo值。