为什么对于使用继承类型的泛型类未检测到类约束? [英] Why is class constraint not detected for generic class using an inherited type?

查看:60
本文介绍了为什么对于使用继承类型的泛型类未检测到类约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提出这个问题很困难,我希望下面的代码片段可以使事情变得清楚:

Phrasing the question was hard, I hope the following code snippet makes things clear:

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);
    }
}

WeakReference需要满足class约束的类型T.到目前为止,还算不错,但是...

The WeakReference requires a type, T, that satisfies a class constraint. So far, so good, but...

为什么(实际上)是T : TBase : class,编译器为什么不能检测到T实际上是真的?

Why can the compiler not detect that T actually does, because (practically) T : TBase : class?

推荐答案

为什么编译器为什么不能检测到T实际上是因为T:TBase:class?

Why can the compiler not detect that T actually does, because (practically) T : TBase : class?

因为那根本不是事实.在中,在他的

Because that is simply not true. On top of what Poke points out in his answer, this is also illegal due to the fact that all value types inherit from object:

 var dc = new DemoClass<object>();
 dc.DemoMethod(1); //woops, just attempted to create a WeakReference<int>

当涉及到值类型时,您的推理就完全瓦解了.人为的?是的,但是完全合法,因此编译器别无选择,必须考虑您的代码非法.

Your reasoning simply falls apart when value types are involved. Contrived? Yes, but perfectly legal so the compiler doesn't have a choice and has to consider your code illegal.

更新

在下面的Jon Hana注释中,在T上面的代码中并不是真正的int,它的object1被隐式装箱了,这绝对是不正确的.考虑以下DemoMethod的变体:

Addressing Jon Hana's comment below that in the code above T is not really int, its object and 1 is boxed implicitly, that is absolutely not true. Consider the following variation of DemoMethod:

public T DemoMethod<T>(T target) where T : TBase
{
    return target;
}

以及以下代码:

var dc = new DemoClass<object>();
var i = dc.DemoMethod(1);

iint,不是object.此外,以下将正确执行:

i is int, its not object. Moreover, the following will execute correctly:

long i = dc.DemoMethod(1);

这也证明了T不能是装箱的int,因为隐式转换将在运行时失败;您不能将值类型开箱,但类型本身除外.

Which also proves the T can not be a boxed int because the implicit conversion would fail at runtime; you can't unbox a value type to anything but the type itself.

当然,您总是可以显式设置T,也可以很好地进行编译:

And of course, you can always set T explicitly, which also compiles just fine:

dc.DemoMethod<int>(1);

这篇关于为什么对于使用继承类型的泛型类未检测到类约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆