18

我可以以某种方式拥有仅因泛型类型约束而不同的重载方法吗?

这不会编译:

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

    }

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

    }

由于这些是“开放”方法,因此当在代码中的其他地方使用具体类型引用实际方法时,它应该是关闭/构造/完全定义的T,然后就会清楚要调用哪个重载。

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

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

4

4 回答 4

11

我可以以某种方式拥有仅因泛型类型约束而不同的重载方法吗?

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

在某些情况下,有一些可怕的“伪重载”方式,但我不建议走这条路。

有关更多信息,您可能需要阅读:

于 2012-09-21T11:53:09.613 回答
5

这是不可能的。

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

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

于 2012-09-21T11:53:17.587 回答
0

更新。在 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()); 
}
于 2018-05-23T13:14:44.027 回答
-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
}
于 2019-07-28T02:43:57.620 回答