I've been playing with interfaces and generics.
What I want is an Foo<T>
to be a shorthand for Foo<T, int>
Is this sensible? Is the following an accepted way of doing it?
using System.Diagnostics;
namespace MyNamespace
{
public class Foo<T> : Foo<T, int> where T : class
{
}
public class Foo<T, U> where T : class
{
public void Bar()
{
Debug.WriteLine("this: " + GetType().Name + ", T: " + typeof(T).Name + ", U: " + typeof(U).Name);
}
}
class Program
{
static void Main(string[] args)
{
var fooT = new Foo<string>();
var fooTU = new Foo<string, int>();
fooT.Bar();
fooTU.Bar();
}
}
}
What my actual question is... is it possible to up (down?) cast from a Foo<T, int>
to a Foo<T>
where T
is the same type. Does it even make sense to say this, or is this something to do with co/contravariance (which still eludes me)?
To me, a somewhat ignorant human, in this example Foo<string>
and Foo<string, int>
are identical types, but of course ((Foo<string>) fooTU).Bar();
does not work!
What my actual question is... is it possible to up (down?) cast from a
Foo<T, int>
to aFoo<T>
where T is the same type. Does it even make sense to say this, or is this something to do with co/contravariance (which still eludes me)?
You can cast from Foo<string, int>
to Foo<string>
if the actual object is of type Foo<T>
. The fact that they have the same name is completely irrelevant here, so let's change that:
class Foo<T, U> {}
class Bar<T> : Foo<T, int>
Now:
Foo<string, int> foo = new Foo<string, int>();
Bar<string> bar = (Bar<string>) foo; // Bang, throws
But:
Foo<string, int> foo = new Bar<string>();
Bar<string> bar = (Bar<string>) foo; // This is fine
The generics are pretty irrelevant here, really... it's the normal rules of casting.
See more on this question at Stackoverflow