将 List<Domain Object> 传递给期望 List<object> 的方法

Passing List<Domain Object> to a Method Expecting List<object>

我知道我缺少泛型或协变的一些基本知识,我希望有更好的方法来完成我正在做的事情。

我有一个方法可以获取域对象列表并将其转换为 HTML table:

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;

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

协变仅在通用接口中受支持。由于看起来 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);

生成你的table.

您应该更改 GenerateTable 以接受对象的 IEnumerable 而不是列表。这样您就不必将客户列表转换为对象列表。

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

您的原始版本的问题是 GenerateTable 可能会尝试将非客户对象添加到列表中。 IEnumerable 之所以有效,是因为它是只读的。如果您有兴趣,可以阅读更多相关内容 here