我想区分以下几种情况:
int
int?
string
我想出了以下代码,在情况(1)和(2)下工作正常:
static void Foo<T>(T a) where T : struct { } // 1 static void Foo<T>(T? a) where T : struct { } // 2
但是,如果我尝试检测这种情况(3),它将无法编译:
static void Foo<T>(T a) where T : class { } // 3
错误消息是 类型’X’已经定义了具有相同参数类型的成员’Foo’ 。好吧,我无法以where T : struct和区别where T : class。
where T : struct
where T : class
如果删除第三个函数(3),则以下代码也不会编译:
int x = 1; int? y = 2; string z = "a"; Foo (x); // OK, calls (1) Foo (y); // OK, calls (2) Foo (z); // error: the type 'string' must be a non-nullable value type ...
如何Foo(z)进行编译,将其映射到上述函数之一(或第三个具有另一个约束的函数,我没有想到)?
Foo(z)
约束不是签名的一部分,但参数是签名的一部分。在重载解析过程中会强制执行参数约束。
因此,让我们将约束放入参数中。很难看,但是可以用。
class RequireStruct<T> where T : struct { } class RequireClass<T> where T : class { } static void Foo<T>(T a, RequireStruct<T> ignore = null) where T : struct { } // 1 static void Foo<T>(T? a) where T : struct { } // 2 static void Foo<T>(T a, RequireClass<T> ignore = null) where T : class { } // 3
(迟到比没有迟到六年吗?)