【发布时间】:2016-09-23 11:00:58
【问题描述】:
是否可以执行以下操作(如果可以,我似乎无法使其正常工作..暂时放弃限制)...
如果类型(因为它被省略了)被推断出来,有什么问题?
private void GetGenericTableContent<T>(ref StringBuilder outputTableContent, T item)
{
outputTableContent.Append("<td>" + item.SpreadsheetLineNumbers + "</td>");
}
// 'item' is either DuplicateSpreadsheetRowModel class or SpreadsheetRowModel class
使用上面的代码,我得到以下错误:
“T”不包含“SpreadsheetLineNumbers”的定义,并且找不到接受“T”类型的第一个参数的扩展方法“SpreadsheetLineNumbers”(您是否缺少 using 指令或程序集引用?)
【问题讨论】:
-
您需要在泛型方法上添加约束,因为当前 T 的类型是 object 和 object
does not contain a definition for 'SpreadsheetLineNumbers'。如果 DuplicateSpreadsheetRowModel 类或 SpreadsheetRowModel 来自实现相同接口的公共基类,则将其用作约束。 -
C# 泛型不是隐式类型的。您的方法签名的编写方式应该可以调用为
GetGenericTableContent(someStringBuilder, 42),使用T = int。显然这会失败,因为int没有成员SpreadsheetLineNumbers所以 C# 正确地拒绝了你的代码。这就是约束的全部意义所在。 -
啊,似乎我错误地认为通过省略它在编译时推断的类型,这就是 MS 所说的“编译器可以根据您传入的方法参数推断类型参数;它不能仅从约束或返回值推断类型参数。”和“编译器只包括那些类型推断成功的泛型方法。” ...所以我猜它成功了哪些类型...嗯...如果它有效,我会添加约束。
-
编译器会在每个调用站点推断通用参数的类型,问题是您的
GetGenericTableContent方法声称适用于任何类型T,但它只能适用于具有适当 @ 的类型987654329@ 财产。描述这种类型的方法是将基类或接口约束添加到T,用于定义所需成员的某些类型。