2014-09-30 36 views
8

我在IList上构建了一个扩展方法,可以将任何传递给它的对象的指定属性作为列表输出,并将其输出为CSV串。它看起来像:如何使用lambda表达式获取代理列表的函数

public static string OutputCSVString<T>(this IList<T> list, List<Func<T, string>> properties) 
{ 
    foreach (var row in list) 
    { 
    foreach(var item in properties) 
    { 
     // Do the output work, including calling item(row). 
    } 
     // Output new line 
    } 
} 

现在,我必须调用此方法,如:

// Assuming I've populated List <Product> ProductList up above... 

var columns = new List<Func<Product, string>>(); 
columns.Add(x => x.Id); 
columns.Add(x => x.Name); 

string s = ProductList.OutputCSVString(columns); 

有没有更好的办法在我的lambda表达式来传递,而无需显式声明的列变量,东西像:

// This doesn't compile 
string s = Products.OutputCSVString(new { p => p.Id , p => p.Name }); 

回答

6

而不是使用List<Func<T, string>>使用Func<T, string>[],并使其成为parameter array

static string OutputCSVString<T>(this IList<T> list, 
           params Func<T, string>[] properties) 

那么你应该能够调用:

string s = Products.OutputCSVString(p => p.Id , p => p.Name); 

请注意,从C#6开始,您应该能够编写:

static string OutputCSVString<T>(this IList<T> list, 
           params IEnumerable<Func<T, string>> properties) 

......这意味着您仍然可以将它与List<Func<T, string>>一起使用。

4

你可以通过你的Lambda表达式作为一个数组,并使用params关键字:

public static string OutputCSVString<T>(this IList<T> list, params Func<T, string>[] properties) 

用法:

string s = Products.OutputCSVString(p => p.Id, p => p.Name); 
5

尝试传递的参数数组

public static string OutputSVString<T>(this IList<T> list, params Func<T, string>[] properties) 
{ 
    ... 
} 

这将让你调用它作为

var s = Products.OutputCSVString(p => p.Id, p => p.Name); 

此外,作为一个建议,放松的函数返回一个对象,然后调用toString ()组装零件时。通过这种方式,您可以将任何属性传递到CSV列表中,而不仅仅是字符串。