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>' */ }
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 aFoo<object>. SupposeFoolooked like this:Then a
Foo<Cat>would always expect aCatvalue for theinputparameter toMethod. But if you could treatFoo<Cat>as aFoo<object>you could do:Now generic variance is available in .NET 4 (and C# 4) but only for interfaces and delegates, and only for those decorated appropriate with
outandinat 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 classFoowhich provides all the members which have nothing to do withT. Then you could write:and all would be well, so long as
Foobulousdidn’t need to use any of the methods which relied onT– which it shouldn’t, given that it can takeFoovalues with different type parameters anyway.