是否有可能做到以下(如果是这样我似乎无法让它工作..暂时放弃约束)...
如果推断出类型(因为它被省略),那么问题是什么?
private void GetGenericTableContent<T>(ref StringBuilder outputTableContent, T item)
{
outputTableContent.Append("<td>" + item.SpreadsheetLineNumbers + "</td>");
}
// 'item' is either DuplicateSpreadsheetRowModel class or SpreadsheetRowModel class
Run Code Online (Sandbox Code Playgroud)
使用上面的代码我收到以下错误:
'T'不包含'SpreadsheetLineNumbers'的定义,并且没有扩展方法'SpreadsheetLineNumbers'可以找到接受类型'T'的第一个参数(你是否缺少using指令或汇编引用?)
Fab*_*jan 21
不,这是不可能的.必须在编译时知道泛型类型.想一想,编译器怎么知道保证类型T有SpreadsheetLineNumbers属性?如果T是原始类型如int或object?
什么阻止我们用ref _, 999参数调用方法(T在这里是int)?
它只有在我们添加包含此属性的接口时才有效:
public interface MyInterface
{
string SpreadsheetLineNumbers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
让你的类继承这个接口
public class MyClass : MyInterface
{
public string SpreadsheetLineNumbers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后使用泛型约束让编译器知道此类型是从此接口继承的,因此它必须包含其所有属性.
private void GetGenericTableContent<T>(ref StringBuilder outputTableContent, T item)
where T : IMyInterface // now compiler knows that T type has implemented all members of the interface
{
outputTableContent.Append("<td>" + item.SpreadsheetLineNumbers + "</td>");
}
Run Code Online (Sandbox Code Playgroud)
如果你不能为你的类型(或几种类型之间的通用)创建一个接口:
private void GetGenericTableContant<T>(ref StringBuilder outputTableContent, T item, Func<T, string> lineNumberAccessor)
{
outputTableContent.Append("<td>" + lineNumberAccessor(item) + "</td>");
}
Run Code Online (Sandbox Code Playgroud)
用法:
GetGenericTableContent(ref outputTableContent, item, x => x.SpreadsheetLineNumbers);
Run Code Online (Sandbox Code Playgroud)
(或者你可以只通过SpreadSheetLineNumbers财产,如果你不是真的需要在方法的项目参考:void GetGenericTableContant<T>(ref StringBuilder outputTableContent, string lineNumbers))