C# 如何获取IEnumerable的第一个元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2317108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:22:52  来源:igfitidea点击:

How to get the first element of IEnumerable

c#.netienumerablelinq-to-objectshtml-lists

提问by Fitzchak Yitzchaki

Is there a better way getting the first element of IEnumerable type of this:

有没有更好的方法来获取 IEnumerable 类型的第一个元素:

foreach (Image image in imgList)
{
     picture.Width = (short)image.Columns;
     picture.Height = (short)image.Rows;
     break;
}

This is the exact declaration of the type:

这是该类型的确切声明:

public class ImageList : IEnumerable, IDisposable

采纳答案by Mark Seemann

var firstImage = imgList.Cast<Image>().First();

回答by Jarrett Meyer

The extension .First()will grab the first item in an enumerable. If the collection is empty, it will throw an exception. .FirstOrDefault()will return a default value for an empty collection (null for reference types). Choose your weapon wisely!

扩展.First()将抓取可枚举中的第一项。如果集合为空,则会抛出异常。.FirstOrDefault()将为空集合返回默认值(引用类型为 null)。明智地选择你的武器!

回答by JonC

If you can't use LINQ you could also get the enumerator directly by imgList.GetEnumerator()And then do a .MoveNext()to move to the first element. .Currentwill then give you the first element.

如果您不能使用 LINQ,您还可以通过imgList.GetEnumerator()And then do a直接获取枚举器,.MoveNext()以移动到第一个元素。 .Current然后会给你第一个元素。

回答by wasatz

Might be slightly irrelevant to your current situation, but there is also a .Single()and a .SingleOrDefault()which returns the first element and throws an exception if there isn't exactly one element in the collection (.Single()) or if there are more than one element in the collection (.SingleOrDefault()).

可能与您当前的情况略有关系,但还有 a.Single()和 a.SingleOrDefault()返回第一个元素并在集合 ( .Single()) 中不完全是一个元素或集合中有多个元素时抛出异常( .SingleOrDefault())。

These can be very useful if you have logic that depends on only having a single (or zero) objects in your list. Although I suspect they are not what you wanted here.

如果您的逻辑仅依赖于列表中的单个(或零个)对象,这些将非常有用。虽然我怀疑它们不是你想要的。

回答by Jürgen Steinblock

I had an issue where I changed my datasource from a bindingsource to an entity framework query.

我遇到了一个问题,我将数据源从绑定源更改为实体框架查询。

var query = dataSource as IQueryable;
var value = query.Where("prop = @0", value).Cast<object>().SingleOrDefault();

With entity framework this throw an exception `Unable to cast the type 'customer' to type 'object'. LINQ to Entities only supports casting EDM primitive or enumeration types.

使用实体框架,这会引发异常`无法将类型'客户'转换为类型'对象'。LINQ to Entities 仅支持转换 EDM 原语或枚举类型。

The class where my code was did not have a reference to the lib with the model so ...Cast<customer>was not possible.

我的代码所在的类没有对模型库的引用,所以...Cast<customer>不可能。

Anyway I used this approach

无论如何我使用了这种方法

var query = dataSource as IQueryable;
var targetType = query.GetType().GetGenericArguments()[0];
var value = query.Where("prop = @0", value).SingleOrDefault(targetType);

in conjunction with an IEnumerable extension which uses reflection

结合使用反射的 IEnumerable 扩展

    public static object SingleOrDefault(this IEnumerable enumerable, Type type)
    {
        var method = singleOrDefaultMethod.Value.MakeGenericMethod(new[] { type });
        return method.Invoke(null, new[] { enumerable });
    }

    private static Lazy<MethodInfo> singleOrDefaultMethod 
         = new Lazy<MethodInfo>(() =>
             typeof(Extensions).GetMethod(
                 "SingleOrDefault", BindingFlags.Static | BindingFlags.NonPublic));

    private static T SingleOrDefault<T>(IEnumerable<T> enumerable)
    {
        return enumerable.SingleOrDefault();
    }

feel free to implement caching per type to improve performance.

随意实现每种类型的缓存以提高性能。