'T'不包含定义

Pau*_*hra 8 c# generics

是否有可能做到以下(如果是这样我似乎无法让它工作..暂时放弃约束)...

如果推断出类型(因为它被省略),那么问题是什么?

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

不,这是不可能的.必须在编译时知道泛型类型.想一想,编译器怎么知道保证类型TSpreadsheetLineNumbers属性?如果T是原始类型如intobject

什么阻止我们用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)


rom*_*aga 5

如果你不能为你的类型(或几种类型之间的通用)创建一个接口:

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))