【问题标题】:Create IEnumerable<T>.Find()创建 IEnumerable<T>.Find()
【发布时间】:2010-06-03 20:46:30
【问题描述】:

我想写:

IEnumerable<Car> cars;
cars.Find(car => car.Color == "Blue")

我可以使用扩展方法来实现吗?以下失败,因为它递归调用自身而不是调用 IList.Find()。

public static T Find<T>(this IEnumerable<T> list, Predicate<PermitSummary> match)
{
    return list.ToList().Find(match);
}

谢谢!

【问题讨论】:

    标签: c# extension-methods ienumerable


    【解决方案1】:

    此方法已存在。它被称为 FirstOrDefault

    cars.FirstOrDefault(car => car.Color == "Blue");
    

    如果你自己实现它,它看起来有点像这样

    public static T Find<T>(this IEnumerable<T> enumerable, Func<T,bool> predicate) {
      foreach ( var current in enumerable ) {
        if ( predicate(current) ) {
          return current;
        }
      }
      return default(T);
    }
    

    【讨论】:

    • 谢谢。没有意识到存在这种过载。
    • 很好的答案!我从未意识到存在这种重载,并且一直在添加多余的 .Where(...).First() 语句。
    【解决方案2】:

    如果您正在寻找一辆蓝色汽车,Jared 是正确的,任何蓝色汽车都足够了。这是您要查找的内容,还是要查找蓝色汽车的列表?

    第一辆蓝色车:

    Car oneCar = cars.FirstOrDefault(c => c.Color.Equals("Blue"));
    

    蓝色汽车列表:

    IEnumerable<Car> manyCars = cars.FindAll(car => car.Color.Equals("Blue"));
    

    【讨论】:

    • 谢谢,如果您正在寻找一辆蓝色汽车:cars.Single(car => car.Color.Equals("Blue")
    • 如果您保证在整个列表中只有一辆车,单车也可以。如果您有不止一辆汽车,或者根本没有汽车,您将抛出 InvalidOperationException。 FirstOrDefault 将返回您的蓝色汽车或默认类型(通常为 null)。如果没有与谓词匹配的内容,First 将抛出异常。
    【解决方案3】:

    你知道Find(...)可以替换成Where / First

    IEnumerable<Car> cars;
    var result = cars.Where(c => c.Color == "Blue").FirstOrDefault();
    

    如果谓词不匹配,这将返回 null

    【讨论】:

    • 不需要 Where。 FirstOrDefault 也将采用谓词。
    • 你可以直接在FirstOrDefault()上指定谓词,把Where()留在外面。
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多