C# 为什么是;式中T:class";本例中是否需要?
示例代码:C# 为什么是;式中T:class";本例中是否需要?,c#,.net,generics,filehelpers,C#,.net,Generics,Filehelpers,示例代码: 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.Ge
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
}
使用System.Collections.Generic;
使用文件助手;
....
私有void保存(字符串destFilename,IEnumerable数据),其中T:class
{
var engine=newfilehelperengine((typeof(T));
engine.HeaderText=engine.GetFileHeader();
engine.WriteFile(destFilename,data);//XX
}
在第XX行,engine.WriteFile的第二个参数应为IEnumerable。这个代码工作正常
我的问题是,为什么方法上需要“where T:class”约束?如果删除它,则会出现编译时错误:
Argument 2: cannot convert from
'System.Collections.Generic.IEnumerable<T>' to
'System.Collections.Generic.IEnumerable<object>'
参数2:无法从转换
“System.Collections.Generic.IEnumerable”到
'System.Collections.Generic.IEnumerable'
我会认为一切都是一个“对象”,所以约束是不必要的 需要约束,因为
对象
仅为引用类型;之所以可以将值类型指定给对象
,是因为装箱(尽管从技术上讲,所有类型都继承自System.object
)
但装箱与类型参数差异是一个单独的问题;带有无约束T的IEnumerable
无法转换为IEnumerable
,因为值类型不支持方差
另一方面,非泛型的FileHelperEngine
继承自的FileHelperEngine
,也有一个T:class
约束。因此,由于只支持引用类型,因此使用约束不会丢失任何功能-理论上可以直接使用FileHelperEngine
,而不必经过非泛型类,因为示例中给出的方法已经是泛型的:
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);
}
使用System.Collections.Generic;
使用文件助手;
....
私有void保存(字符串destFilename,IEnumerable数据),其中T:class
{
var engine=new FileHelperEngine();
engine.HeaderText=engine.GetFileHeader();
engine.WriteFile(文件名、数据);
}
您要将T
应用于FileHelperEngine
,它已经具有相同的约束,T:class
。编译器可以告诉您,如果您没有对方法施加相同的约束,则t
可能对FileHelperEngine
无效。
所以这只是为了防止类型不匹配。谢谢。另外,关于FileHelpers的最后一段也很好,如果您使用FileHelperEngine,就像BoltClock的示例一样,这是正确的。但在使用FIleHelperEngine(类型recordType)时,情况似乎与我最初的示例不同。