Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I cast in my lambda or cast the IEnumerable?

Tags:

c#

casting

linq

In my project I have a MyClass which implements IMyClass. I need to return a list of IMyClass by transforming a list of other items. For simplicity's sake, assume that I can create a MyClass just by passing another item into its constructor, i.e. new MyClass(item).

Consider the following two lines, which (as far as I know) produce the same result:

var option1 = items.Select(item => new MyClass(item)).Cast<IMyClass>().ToList()
var option2 = items.Select(item => new MyClass(item) as IMyClass).ToList()

It seems to me that option #1 would require a double enumeration, once to cast all the items to my interface and once to generate the list. If I'm right then option #2 would be smarter. However, I've never seen any code using something like option #2, and I tend to assume that I'm not smart enough to come up with something clever that the rest of the C# community did not.

On a side note, I think option #2 is more aesthetically pleasing, but that's just me.

My question is: is my option #2 a better idea like I think it is? Are there are any gotchas I'm missing or other reasons why I'd want to stick with option #1? Or am I perhaps comparing two stupid ideas when there is a smarter third one that I'm missing completely?

like image 853
ean5533 Avatar asked Mar 01 '13 17:03

ean5533


People also ask

Which is faster Linq or Lambda?

Both yields the same result because query expressions are translated into their lambda expressions before they're compiled. So performance-wise, there's no difference whatsoever between the two.

What is the use of cast in linq c#?

LINQ Cast() Method In LINQ, Cast operator is used to cast/convert all the elements present in a collection into a specified data type of new collection. In case if we try to cast/convert different types of elements (string/integer) in the collection, then the conversion will fail, and it will throw an exception.

How to cast a method c#?

To cast elements, use the Cast() method. The following is our list. List<object> myList = new List<object> { "Mac", "Windows", "Linux", "Solaris" }; Now, cast and use the Cast() method with substring() method to display the first two letters of every string in the list.


2 Answers

I'd go for option 3:

var option3 = items.Select<Foo, IMyClass>(item => new MyClass(item))
                   .ToList()

Alternatively, don't use as but just cast normally:

var option4 = items.Select(item => (IMyClass) new MyClass(item))
                   .ToList()

Both of these seem cleaner than using Cast.

Oh, and as of C# 4 with .NET 4 (due to covariance), you could put a type argument on the ToList call instead:

var option5 = items.Select(item => new MyClass(item))
                   .ToList<IMyClass>()
like image 119
Jon Skeet Avatar answered Oct 16 '22 01:10

Jon Skeet


It seems to me that option #1 would require a double enumeration

This is not true. In both cases, the items collection is only enumerated when you get to ToList().

The line

var option1 = items.Select(item => new MyClass(item)).Cast<IMyClass>().ToList()

is equivalent to

var option1 = items.Select(item => new MyClass(item)).Select(x => (IMyClass)x).ToList()

The only difference between the two is that the first one requires two function calls per item (unless C# inlines the lambdas somehow, which I don't believe is the case) while the second option requires only one.

Personally, I'd go with the second one as a matter of style.

like image 3
p.s.w.g Avatar answered Oct 16 '22 02:10

p.s.w.g