Reputation: 9163
Is there a better way getting the first element of IEnumerable type of this:
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
Upvotes: 18
Views: 28482
Reputation: 31723
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.
The class where my code was did not have a reference to the lib with the model so ...Cast<customer>
was not possible.
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
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.
Upvotes: 0
Reputation: 4278
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()
).
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.
Upvotes: 0
Reputation: 809
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.
.Current
will then give you the first element.
Upvotes: 10
Reputation: 19573
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!
Upvotes: 6