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

我想区分以下几种情况:


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


冉冉说
浏览 627回答 3
3回答

胡子哥哥

约束不是签名的一部分,但参数是签名的一部分。在重载解析过程中会强制执行参数约束。因此,让我们将约束放入参数中。很难看,但是可以用。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 { } // 1static void Foo<T>(T? a) where T : struct { } // 2static void Foo<T>(T a, RequireClass<T> ignore = null) where T : class { } // 3(迟到比没有迟到六年吗?)

BIG阳

在第一种方法上删除结构约束。如果需要区分值类型和类,则可以使用参数的类型来实现。&nbsp; &nbsp; &nbsp; static void Foo( T? a ) where T : struct&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// nullable stuff here&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; static void Foo( T a )&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( a is ValueType )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ValueType stuff here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // class stuff&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP