示例代码:
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&lt; object&gt;。这段代码工作正常。
我的问题是,为什么方法需要“where T:class”约束?如果我删除它,我得到编译时错误:
Argument 2: cannot convert from
'System.Collections.Generic.IEnumerable<T>' to
'System.Collections.Generic.IEnumerable<object>'
我原以为一切都是“对象”,所以约束不是必要的?
答案 0 :(得分:6)
需要约束,因为object
仅是引用类型;可以将值类型分配给object
的原因是拳击(尽管从技术上讲,所有类型都继承自System.Object
)。
但拳击是类型参数方差的一个独立问题;具有无约束T的IEnumerable<T>
无法转换为IEnumerable<object>
,因为值类型不支持方差。
另外,非通用FileHelperEngine<T>
继承的FileHelperEngine
(作为FileHelperEngine<object>
)也有T : class
约束。所以你不会因为只有支持引用类型而没有错过任何功能 - 理论上可以直接使用FileHelperEngine<T>
而不通过非泛型类,因为样本中给出的方法是已经通用:
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);
}
答案 1 :(得分:0)
您已将T
应用于已具有相同约束的FileHelperEngine<T>
T : class
。编译器可以告诉您,如果您不对您的方法施加相同的约束,则T
可能对FileHelperEngine<T>
无效。
所以它只是防止类型不匹配。