使用LINQ在列表中查找特定类型的第一个元素

25

如何使用 LINQ 和 C# 以最短的方式查找列表中某种类型的第一个项。

5个回答

38
var first = yourCollection.OfType<YourType>().First();

注意,如果没有YourType类型的元素,则First方法会抛出异常。如果不想这样,可以使用FirstOrDefaultTake(1),具体取决于您想要的行为。

15

使用OfType扩展方法:

public static T FindFirstOfType<T>(IEnumerable list){
 return list.OfType<T>().FirstOrDefault();
}

4
将这个 IEnumerable 列表转换为扩展方法? - Yuriy Faktorovich

8

6
您可以使用 FirstOrDefault 方法,并传递用于比较的委托。
object[] list = new object[] {
    4,
    "something",
    3,
    false,
    "other"
};

string first = list.FirstOrDefault(o => o is string); //something

你的代码无法编译。因为 FirstOrDefault 返回一个 object,你需要将其转换为 string 才能将其赋值给第一个声明为 string 的变量。 - Mariano Desanze

0

我建议使用hugoware的答案,以避免不必要的迭代:

(string)source.FirstOrDefault(f => f is string)

但是如果你担心微小的优化问题,你可以创建自己的扩展方法:

public static class ListExtensions
{
    public static T FirstOrDefault<T>(this IList source)
    {
        for (int i = 0; i < source.Count; i++)
        {
            if (source[i] is T)
                return (T)source[i];
        }
            
        return default;
    }
}

使用包含 100 个对象的列表进行基准测试,其中仅最后一个是字符串(dotnet 7,BenchmarkDotNet):

[Benchmark]
public string OfType_First() => objects.OfType<string>().FirstOrDefault();

[Benchmark]
public string FirstOrDefault() => (string)objects.FirstOrDefault(f => f is string);

[Benchmark]
public string FirstOrDefault_T() => objects.FirstOrDefault<string>();

|           Method | Size |       Mean |    Error |    StdDev | Allocated |
|----------------- |----- |-----------:|---------:|----------:|----------:|
|     OfType_First |  100 | 1,229.0 ns | 57.86 ns | 157.41 ns |      96 B |
|   FirstOrDefault |  100 |   920.1 ns | 18.31 ns |  31.59 ns |      40 B |
| FirstOrDefault_T |  100 |   671.4 ns | 12.24 ns |  15.91 ns |         - |

// * Legends *
  Size      : Value of the 'Size' parameter
  Mean      : Arithmetic mean of all measurements
  Error     : Half of 99.9% confidence interval
  StdDev    : Standard deviation of all measurements
  Median    : Value separating the higher half of all measurements (50th percentile)
  Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
  1 ns      : 1 Nanosecond (0.000000001 sec)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接