如何使用 LINQ 和 C# 以最短的方式查找列表中某种类型的第一个项。
var first = yourCollection.OfType<YourType>().First();
YourType
类型的元素,则First
方法会抛出异常。如果不想这样,可以使用FirstOrDefault
或Take(1)
,具体取决于您想要的行为。使用OfType扩展方法:
public static T FindFirstOfType<T>(IEnumerable list){
return list.OfType<T>().FirstOrDefault();
}
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我建议使用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)