How do you provide a default type for generics?

The compiler can infer the type arguments on methods most of the time based on the type of the arguments passed:

public void DoSomething<T>(T test) {
}

can be called with

DoSomething(4);                   // = DoSomething<int>(4);
DoSomething(MyEnum.SomeValue);    // = DoSomething<MyEnum>(MyEnum.SomeValue);

By the way, you can have non-generic overloads of a generic method too.


You can't do it in the definition of the class:

var foo = new MyGenericClass(); // defaults to integer... this doesn't work
var bar = new MyGenericClass<MyEnum>(); // T is a MyEnum

If really value the implicitness of the default type being int, you'll have to do it with a static factory method, although I don't see the value of it.

public class MyGenericClass<T>
{
    public static MyGenericClass<T> Create()
    {
        return new MyGenericClass<T>();
    }
    public static MyGenericClass<int> CreateDefault()
    {
        return new MyGenericClass<int>();
    }
}

See below for how you really don't benefit from the above.

var foo = MyGenericClass<MyEnum>.Create();
var bar1 = MyGenericClass.CreateDefault(); // doesn't work
var bar2 = MyGenericClass<int>.CreateDefault(); // works, but what's the point

If you want to take it even farther, you can create a static factory class that will solve this, but that's an even more ridiculous solution if you're doing it for no other reason than to provide a default type:

public static class MyGenericClassFactory
{
    public static MyGenericClass<T> Create<T>()
    {
        return new MyGenericClass<T>();
    }
    public static MyGenericClass<int> Create()
    {
        return new MyGenericClass<int>();
    }
}

var foo = MyGenericClassFactory.Create(); // now we have an int definition
var bar = MyGenericClassFactory.Create<MyEnum>();

Keep your original version (non-generic version) and create a generic version of it.

Then call the generic version from your non-generic version.

void Main()
{
DoSomething(2);
DoSomething(EnumValue);

}

public void DoSomething(int test) {
DoSomething<int>(test);
}

// Define other methods and classes here
public void DoSomething<T>(T test) {
Console.WriteLine(test);
}

So... why not use simple inheritance? Like:

class MyGenericClass<T>
{
}

class MyGenericClass : MyGenericClass<int>
{
}

This way you can write both ways:

var X = new MyGenericClass<string>();
var Y = new MyGenericClass(); // Is now MyGenericClass<int>