为什么使用继承类型的泛型类未检测到类约束?

2024-04-17

表达这个问题很难,我希望下面的代码片段能让事情变得清楚:

public class DemoClass<TBase> where TBase : class
{
    public void DemoMethod<T>(T target) where T : TBase
    {
        //The following line causes a design-time error: Type argument 'T' does not satisfy the 'Class' constraint for type parameter 'T'.
        WeakReference<T> demoRef = new WeakReference<T>(target);
    }
}

The WeakReference需要一个类型,T,满足class约束。到目前为止,一切都很好,但是……

为什么编译器检测不到T实际上确实如此,因为(实际上)T : TBase : class?


为什么编译器无法检测到 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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么使用继承类型的泛型类未检测到类约束? 的相关文章

随机推荐