首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么没有检测到使用继承类型的泛型类的类约束?

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

Stack Overflow用户
提问于 2017-07-05 06:39:46
回答 2查看 463关注 0票数 6

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

代码语言:javascript
复制
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。到目前为止一切都还好但是..。

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

EN

回答 2

Stack Overflow用户

发布于 2017-07-05 07:13:49

类为什么编译器不能检测到T确实检测到了,因为(实际上)T: TBase:

因为这根本不是真的。除了Poke在他的answer中指出的,这也是非法的,因为所有的值类型都继承自object

代码语言:javascript
复制
 var dc = new DemoClass<object>();
 dc.DemoMethod(1); //woops, just attempted to create a WeakReference<int>

当涉及值类型时,您的推理就会分崩离析。人为的?是的,但是完全合法,所以编译器没有选择,必须认为你的代码是非法的。

更新

Jon Hana在下面的评论中说,在上面的代码中,T不是真正的int,它的object1被隐式地包装起来,这绝对不是真的。考虑DemoMethod的以下变体

代码语言:javascript
复制
public T DemoMethod<T>(T target) where T : TBase
{
    return target;
}

和以下代码:

代码语言:javascript
复制
var dc = new DemoClass<object>();
var i = dc.DemoMethod(1);

iint,它不是object。此外,以下代码将正确执行:

代码语言:javascript
复制
long i = dc.DemoMethod(1);

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

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

代码语言:javascript
复制
dc.DemoMethod<int>(1);
票数 5
EN

Stack Overflow用户

发布于 2017-07-05 06:50:15

让我们来看看the documentation关于T : class的实际含义:

where T : class

类型参数必须是引用类型;这也适用于任何类、接口、委托或数组类型。

不幸的是,如果T是一个接口,这就已经满足了。因此,您可以构造一个简单的示例,从中可以看到传递地应用T : class将不起作用:

代码语言:javascript
复制
public interface ITest { }
public struct Test : ITest { }

如果您现在创建一个类,那么您就满足了类型约束,因为ITest在这里是一个“类”。但是,当您调用DemoMethod<Test>方法时,虽然Test继承了ITest,但是您没有T的引用类型。

通常,这些特殊的泛型类型约束不遵循继承规则。这就是为什么它们是单独定义的,并且还没有由类型系统建立。它们是作为一种特殊的语法存在的,因为类型系统不能以其他方式表达约束。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44914808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档