2010-02-23 37 views
13

的第一個元素是沒有更好的方法獲得的IEnumerable類型的這的第一個元素:如何獲得的IEnumerable

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

這是該類型的確切聲明:

public class ImageList : IEnumerable, IDisposable 
+0

爲什麼你不使用通用'IEnumerable '所以'ImageList'可能來自'IEnumerable '? – 2010-02-23 09:57:42

+1

@Arnis:因爲ImageLIst defien在ImageMagick.net庫... :) – 2010-02-23 10:00:40

回答

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

@Mark,是需要的Cast。不能我們只是使用「var firstImage = ImgList.First()」?? – RameshVel 2010-02-23 10:04:34

+4

@Ramesh:'Cast'在這種情況下是必需的,因爲'First'是爲'IEnumerable '實現的,但'ImageList'只實現'IEnumerable'。 – 2010-02-23 10:06:11

+1

@Ramesh Vel,你不能使用imgList.First(),因爲它在投射之前不是一個通用的IEnumerable 。 – JonC 2010-02-23 10:07:22

5

分機.First()將抓取可枚舉的第一個項目。如果集合是空的,它將拋出異常。 .FirstOrDefault()將返回空集合的默認值(對於引用類型爲null)。明智地選擇你的武器!

10

如果你不能使用LINQ,你也可以通過imgList.GetEnumerator() 直接得到枚舉器然後做一個.MoveNext()移動到第一個元素。然後 .Current會給你第一個元素。

0

可能會略有無關你目前的情況,但也有一個.Single().SingleOrDefault()返回的第一個元素,並拋出一個異常,如果有集合(.Single())中的一個元素是不是或者有更比集合中的一個元素(.SingleOrDefault())。

如果您的邏輯取決於列表中只有一個(或零個)對象,這些可能非常有用。雖然我懷疑他們不是你想要的東西。

+0

其實我知道Linq很好,但IEnumerable很混亂,因爲經常使用'IEnumerable '。 – 2010-02-23 10:13:53

0

我有一個問題,我將數據源從bindingsource更改爲實體框架查詢。

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

使用實體框架,會拋出一個異常`無法將類型'customer'強制類型轉換爲'object'。 LINQ to Entities僅支持投射EDM基元或枚舉類型。

我的代碼所在的類沒有對模型庫的引用,所以...Cast<customer>是不可能的。

反正我用這種方法

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

與此相關,使用反射

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(); 
    } 

隨時實現每種類型的緩存來提高性能的IEnumerable的擴展。