将List <domain object =“”>传递给方法期望列表<object>

时间:2015-04-30 16:09:06

标签: c# generics covariance

我知道我遗漏了一些基本的泛型或协方差,我希望有更好的方法来做我正在做的事情。

我有一个方法,它获取域对象列表并将其转换为HTML表格:

public String GenerateTable(List<object> Data, String[] Properties,
    String[] ColumnHeaders = null)
{
}

当我调用该方法时,我发现自己必须这样做:

List<Customer> cust = GetCustomers();
List<object> oCust = new List<object>;
foreach (Customer c in cust)
    oCust.Add((object)c);

string table = GenerateTable(oCust, new string[] { "CustNbr", "CustName" });

我相信协方差我可以简单地说:

List<object> oCust = cust;

但是,我正在寻找一种更好的全方位解决方案 - 无需每次运行此方法时创建一个全新的列表。这不是性能或内存问题,因为这些列表总是相对较小,但我想了解实现此目的的最佳(或至少更好)方法。

2 个答案:

答案 0 :(得分:3)

您应该更改GenerateTable以接受IEnumerable对象而不是列表。然后,您不必将客户列表转换为对象列表。

public String GenerateTable(IEnumerable<object> Data, String[] Properties, String[] ColumnHeaders = null)

原始版本的问题是GenerateTable可能会尝试将非Customer对象添加到List。 IEnumerable有效,因为它是只读的。如果您有兴趣,可以阅读更多相关信息here

答案 1 :(得分:2)

协方差仅在通用接口中受支持。由于看起来IEnumerable就足够了,所以你可以尝试不使用泛型。

public string GenerateTable(IEnumerable data, string[] properties, string[] columnHeaders = null)

或者,您可以设置通用转换方法

public string GenerateRow(Customer customer) { // convert one object here} 

public string GenerateTable<T>(List<T> objects, Func<T,string> rowGenerator) 
{
   // table boilerplate
   foreach(var obj in objects) {
     output.Append(rowGenerate(customer)) 
   }
}

然后用

调用它
var table = GenerateTable(customerList, GenerateRow);

生成你的表格。