基于通用约束的方法重载?

时间:2012-09-21 11:47:52

标签: c# generics

我可以以某种方式重载只有通用类型约束不同的重载方法吗?

这不编译:

    void Foo<T>(T bar) where T : class
    {

    }

    void Foo<T>(T bar) where T : struct
    {

    }

由于这些是“开放”方法,当实际方法在具有类型T的代码中引用时,应该关闭/构造/完全定义,然后将清楚调用哪个重载。

显而易见的解决方案不是让它们超载,但我想知道为什么这在C#中不起作用?

附加问题:如果这只是一个C#编译器约束,IL是否允许这样的重载?

4 个答案:

答案 0 :(得分:10)

  

我可以以某种方式重载只有泛型类型约束的重载方法吗?

没有。就重载而言,它不是方法签名的一部分,就像返回类型不是。

在某些情况下,存在horrible种“伪重载”方式,但我不建议沿着这条路走下去。

有关详细信息,您可能需要阅读:

答案 1 :(得分:5)

这是不可能的。

出于重载的目的,通用约束不被视为方法签名的一部分。

如果您想同时允许值类型和引用类型,为什么要限制?

答案 2 :(得分:1)

更新。在C#7.3中,泛型约束现在是重载决策的一部分。

所以,这段代码将编译:

class Animal { } 
class Mammal : Animal { } 
class Giraffe : Mammal { }
class Reptile : Animal { } 

static void Foo<T>(T t) where T : Reptile { }
static void Foo(Animal animal) { }
static void Main() 
{ 
    Foo(new Giraffe()); 
}

答案 3 :(得分:-1)

struct _Val_Trait<T> where T:struct { }
struct _Ref_Trait<T> where T:class { }

static void Foo<T>(T bar, _Ref_Trait<T> _ = default(_Ref_Trait<T>)) where T:class
{
    Console.WriteLine("ref");
}

static void Foo<T>(T bar, _Val_Trait<T> _ = default(_Val_Trait<T>)) where T:struct
{
    Console.WriteLine("val");
}

static void Main() 
{
    Foo(1);            // -->"val"
    Foo(DateTime.Now); // -->"val"
    Foo("");           // -->"ref"

    //but:
    //Foo(null); - error: type cannot be inferred
}