Call non-generic Method(Generic<Base>[] args) and pass array of Generic<Derived>?
Solution to call non-generic method and pass generic arguments with different generic types?
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
My reality:
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!
In summary:
void Fee(object[] params) { /* WORKS! But not constrained to 'Foo<Base>' */ }
void Fie(Foo<Cat>[] params) { /* Does not accept 'Foo<Dog&开发者_如何学Cgt;' */ }
void Foe(Foo<>[] params) { /* ERROR: 'Type expected' */ }
void Fum(Foo<object>[] params) { /* Cannot convert 'Foo<Cat>' to 'Foo<object>' */ }
Clearly, this can't be done... Is there a clean alternative?
The problem is that a Foo<Cat>
isn't a Foo<object>
. Suppose Foo
looked like this:
public class Foo<T>
{
public void Method(T input)
{
...
}
}
Then a Foo<Cat>
would always expect a Cat
value for the input
parameter to Method
. But if you could treat Foo<Cat>
as a Foo<object>
you could do:
Foo<Cat> catFoo = new Foo<Cat>();
Foo<object> objectFoo = catFoo;
objectFoo.Method(new object()); // Eek! Type safety is broken!
Now generic variance is available in .NET 4 (and C# 4) but only for interfaces and delegates, and only for those decorated appropriate with out
and in
at the point of the type parameter declaration. That may or may not be useful to you.
Another option is to make Foo<T>
derive from an abstract non-generic base class Foo
which provides all the members which have nothing to do with T
. Then you could write:
void Foobulous(Foo[] fooArray)
...
Foobulous(new Foo[] {
new Foo<object>(),
new Foo<Cat>(),
new Foo<Dog>()
});
and all would be well, so long as Foobulous
didn't need to use any of the methods which relied on T
- which it shouldn't, given that it can take Foo
values with different type parameters anyway.
精彩评论