Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic contraints on method overloads

I've got an interface with some generic methods, and I wanted to implement a method with overloads to either accept an instance of a class, or its PK value (which is either an int or GUID but does vary).

I added to methods similar to these examples:

    void DoSomething<TKey>(TKey key) where TKey: struct;
    void DoSomething<TModel>(TModel model) where TModel : class;

The 'DoSomething' method name on the second of these is highlighted, and the error is

Type 'ISomeStuff' already defines a member called 'DoSomething' with the same parameter types.

I'm surprised by this as I've clearly defined by parameters to be of different type: one is a class and the other a struct.

Why isn't this sufficient to make the signatures different?

like image 222
Jon Egerton Avatar asked Oct 14 '11 08:10

Jon Egerton


1 Answers

Is possible to do it, you need create something like enable_if from C++

public class ClassTag<V> where V : class { }

public class StructTag<V> where V : struct { }

public void Func<V>(V v, ClassTag<V> dummy = null) where V : class
{
    Console.Writeln("class");
}

public void Func<V>(V v, StructTag<V> dummy = null) where V : struct
{
    Console.Writeln("struct");
}

public void Func<V>(V? v, StructTag<V> dummy = null) where V : struct
{
    Console.Writeln("struct?");
}

static void Main()
{
    Func("A");
    Func(5);
    Func((int?)5);
}

It can be expanded to use any disjoint where to distinguish between overloads. Only drawback is that It cant be used inside another generic method:

public static void Z1<T>(T t) // where T : class
{
    Func(t); //error there
}

public static void Z2<T>(T t) where T : class
{
    Func(t); //ok 
}

edit But there is possibility of use dynamic in that case to work around this limitation:

public static void Z1<T>(T t)
{
     Func((dynamic)t); //if `T == int` it will call "struct" version
}

Only drawback is run time cost similar to call to Dictionary<,> index.

like image 133
Yankes Avatar answered Sep 17 '22 22:09

Yankes