我想区分以下情况:
- 普通值类型(例如
int
) - 可空值类型(例如
int?
) - 引用类型(例如
string
)- 可选,我不关心它是否映射到上面的 (1) 或 (2)
我想出了以下代码,它适用于情况 (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
。
如果我删除第三个函数 (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)
进行编译,将其映射到上述函数之一(或具有另一个约束的第三个函数,我没有想到)?
最佳答案
约束不是签名的一部分,但参数是。并且在重载决策期间强制执行参数中的约束。
所以让我们将约束放在参数中。这很丑陋,但它确实有效。
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
(迟到六年总比没有好?)
关于c# - 通用约束,其中 T : struct and where T : class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2974519/