C# Generic Shorthand and Upcasting

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!

Jon Skeet
people
quotationmark

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)?

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.

people

See more on this question at Stackoverflow