一尘不染

通用约束,其中T:struct和T:class

c#

我想区分以下几种情况:

  1. 普通值类型(例如int
  2. 可为空的值类型(例如int?
  3. 引用类型(例如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)进行编译,将其映射到上述函数之一(或第三个具有另一个约束的函数,我没有想到)?


阅读 310

收藏
2020-05-19

共1个答案

一尘不染

约束不是签名的一部分,但参数是签名的一部分。在重载解析过程中会强制执行参数约束。

因此,让我们将约束放入参数中。很难看,但是可以用。

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

(迟到比没有迟到六年吗?)

2020-05-19