首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么在这个例子中需要"where T: class“?

为什么在这个例子中需要"where T: class“?
EN

Stack Overflow用户
提问于 2016-03-10 04:55:38
回答 2查看 319关注 0票数 4

样本代码:

代码语言:javascript
代码运行次数:0
运行
复制
using System.Collections.Generic;
using FileHelpers;

....
private void Save<T>(string destFilename,  IEnumerable<T> data) where T : class    
{
    var engine = new FileHelperEngine((typeof(T)));


    engine.HeaderText = engine.GetFileHeader(); 
    engine.WriteFile(destFilename, data); // XX
}

在第XX行,engine.WriteFile的第二个参数期待一个IEnumerable。这段代码工作正常。

我的问题是,为什么方法需要"where T: class“约束?如果删除它,将得到编译时错误:

代码语言:javascript
代码运行次数:0
运行
复制
Argument 2: cannot convert from
'System.Collections.Generic.IEnumerable<T>' to
'System.Collections.Generic.IEnumerable<object>'

我原以为一切都是“对象”,所以没有必要加以约束?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-10 05:02:42

之所以需要约束,是因为object只是一个引用类型;可以将值类型分配给object的原因是装箱(尽管从技术上讲,所有类型都是从System.Object继承的)。

但是装箱是一个与类型参数方差不同的问题;具有无约束T的IEnumerable<T>不能转换为IEnumerable<object>,因为值类型不支持方差。

顺便说一下,FileHelperEngine<T> (非泛型FileHelperEngine继承自(作为FileHelperEngine<object>) )也有一个T : class约束。因此,您不会因为具有约束而缺少任何功能,因为无论如何都只支持引用类型--理论上可以直接使用FileHelperEngine<T>而不需要遍历非泛型类,因为示例中给出的方法已经是泛型的:

代码语言:javascript
代码运行次数:0
运行
复制
using System.Collections.Generic;
using FileHelpers;

....
private void Save<T>(string destFilename,  IEnumerable<T> data) where T : class    
{
    var engine = new FileHelperEngine<T>();


    engine.HeaderText = engine.GetFileHeader(); 
    engine.WriteFile(destFilename, data);
}
票数 6
EN

Stack Overflow用户

发布于 2016-03-10 12:50:42

您将将T应用于已经具有相同约束的FileHelperEngine<T>T : class。编译器可以判断,如果您不对您的方法施加相同的约束,那么T可能对FileHelperEngine<T>无效。所以这只是为了防止类型不匹配。

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

https://stackoverflow.com/questions/35907892

复制
相关文章

相似问题

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