如何使用lambda和功能C#范例删除不必要的列表

时间:2009-10-08 12:32:19

标签: c# linq lambda

Hello Functional C#Friends,

所以这次我试图压缩我的代码并编写更多功能,lambda样式,以及我想创建不必要的列表和类,让编译器为我工作。我确实设法以功能方式转换了一小段代码但在那之后我对如何去做并不太了解。

var errorList = new List<DataRow>();

IEnumerable<DataRow> resultRows = GetResultRows();

resultRows      
     .Filter(row => row.Field<string>("status").Equals("FAILURE", StringComparison.InvariantCultureIgnoreCase))
     .ForEach(row => { errorList.Add(row); });

if (errorList.Count > 0)
{
    var excludedBooks = new List<string>();
    foreach (DataRow row in errorList)
    {
        if (ToUseBooksList.Contains((string)row["main_book"]))
        {
            BookCheckResults.AddRow(string.Format("Error for MainBook {0}, RiskType {1}",
                                                  row["main_book"], row["risk_type"]));
            if (!excludedBooks.Contains((string)row["main_book"]))
            {
                excludedBooks.Add((string)row["main_book"]);
            }
        }
    }
}

我的扩展方法:

public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
    if (collection == null)
        throw new ArgumentNullException("collection");
    if (action == null)
        throw new ArgumentNullException("action");

    foreach (var item in collection)
        action(item);
}

public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Predicate<T> func)
{
    foreach (var item in source)
    {
        if (func(item))
            yield return item;
    }
}

如果你能帮我构建这段代码,我将非常感激,这种代码更具实用性,lambda风格。

2 个答案:

答案 0 :(得分:9)

为什么在Filter可用时您是否编写了自己的Where扩展方法?

答案 1 :(得分:4)

ForEach扩展方法通常不值得打扰。

Eric Lippert has blogged about it,他对它的哲学反对意见是它看起来像一个副作用自由表达(就像大多数Linq的特征一样),但它实际上是一种伪装的副作用命令陈述。

如果要对列表中的每个项目执行操作,请使用foreach语句。这就是它的用途。

如果你想操纵动作列表,那么你可以这样做,但是你需要IEnumerable<Action>

对于代码的第一部分,如何:

var errorList = GetResultRows().Where(row => row.Field<string>("status").Equals("FAILURE", StringComparison.InvariantCultureIgnoreCase)
                               .ToList();

您有List<string>被称为排除的图书。请改用HashSet<string>,而不需要检查是否已添加字符串:

var excludedBooks = new HashSet<string>();
foreach (DataRow row in errorList)
{
    if (ToUseBooksList.Contains((string)row["main_book"]))
    {
        BookCheckResults.AddRow(string.Format("Error for MainBook {0}, RiskType {1}",
                                              row["main_book"], row["risk_type"]));

        excludedBooks.Add((string)row["main_book"]);
    }
}

您还可以使用Where过滤列表:

var excludedBooks = new HashSet<string>();
foreach (DataRow row in errorList.Where(r => ToUseBooksList.Contains((string)r["main_book"]))
{
    BookCheckResults.AddRow(string.Format("Error for MainBook {0}, RiskType {1}",
                                              row["main_book"], row["risk_type"]));

    excludedBooks.Add((string)row["main_book"]);
}