为什么编译器无法检测到 T 实际上可以检测到,因为(实际上) T : TBase : class ?
因为那根本不是真的。在什么之上Poke https://stackoverflow.com/users/216074/poke指出他的answer https://stackoverflow.com/a/44914885/767890,这也是非法的,因为所有值类型都继承自 object
:
var dc = new DemoClass<object>();
dc.DemoMethod(1); //woops, just attempted to create a WeakReference<int>
当涉及值类型时,你的推理就会崩溃。做作?是的,但完全合法,因此编译器别无选择,必须认为您的代码非法。
UPDATE
解决上面代码中 Jon Hana 的评论T
不是真的int
, its object
and 1
是隐式装箱的,这绝对不是真的。考虑以下变化DemoMethod
:
public T DemoMethod<T>(T target) where T : TBase
{
return target;
}
以及以下代码:
var dc = new DemoClass<object>();
var i = dc.DemoMethod(1);
i
is int
, 它不是object
。此外,以下内容将正确执行:
long i = dc.DemoMethod(1);
这也证明了T
不能是盒装的int
因为隐式转换在运行时会失败;除了类型本身之外,您无法将值类型拆箱为任何类型。
当然,您可以随时设置T
明确地,它也编译得很好:
dc.DemoMethod<int>(1);