代码之家  ›  专栏  ›  技术社区  ›  netmatrix01

如何使用lambda和函数C范式删除不必要的列表

  •  0
  • netmatrix01  · 技术社区  · 16 年前

    你好,功能C朋友们,

    所以这一次我尝试压缩我的代码,用更实用的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 回复  |  直到 16 年前
        1
  •  4
  •   Daniel Earwicker    16 年前

    foreach扩展方法通常不值得麻烦。

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

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

    如果你想操作操作列表,那么你可以这样做,但是你需要 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"]);
    }
    
        2
  •  9
  •   leppie    16 年前

    你到底为什么要自己写 Filter 扩展方法 Where 有空吗?