Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the C# compiler allow an explicit cast between IEnumerable<T> and TAlmostAnything?

The following code gives you a compiler error, as you'd expect:

List<Banana> aBunchOfBananas = new List<Banana>();  Banana justOneBanana = (Banana)aBunchOfBananas; 

However, when using IEnumerable<Banana>, you merely get a runtime error.

IEnumerable<Banana> aBunchOfBananas = new List<Banana>();  Banana justOneBanana = (Banana)aBunchOfBananas; 

Why does the C# compiler allow this?

like image 260
Danny Avatar asked Feb 08 '12 17:02

Danny


People also ask

Why does the C exist?

Like the letter G, C emerged from the Phoenician letter gimel (centuries later, gimel became the third letter of the Hebrew alphabet). In ancient Rome, as the Latin alphabet was being adapted from the Greek and Etruscan alphabets, G and C became disambiguated by adding a bar to the bottom end of the C.

Is the letter C useless?

But yeah, here are all the letters from most useless to most useful: X, C, Q, Y, W, H, Z, V, B, D, G, P, E, M, L, U, J, R, F, N, K, A, I, T, S, O. I hope you enjoyed this.

Does the letter C need to exist?

This is a very important rule considering about 25% of words in our language contain a C.] So why do we need a C? When we combine the C with an H we DO make a unique sound. Without a C we would go to Hurch instead of Church, we would listen to a Hime instead of a Chime, etc.


1 Answers

I would suppose it's because IEnumerable<T> is an interface where some implementation could have an explicit cast to Banana - no matter how silly that would be.

On the other hand, the compiler knows that List<T> can't be explicitly cast to a Banana.

Nice choice of examples, by the way!

Adding an example to clarify. Maybe we'd have some "enumerable" that should always contain at most a single Banana:

public class SingleItemList<T>:Banana, IEnumerable<T> where T:Banana {     public static explicit operator T(SingleItemList<T> enumerable) {         return enumerable.SingleOrDefault();     }      // Others omitted... } 

Then you could actually do this:

IEnumerable<Banana> aBunchOfBananas = new SingleItemList<Banana>(); Banana justOneBanana = (Banana)aBunchOfBananas; 

As it's the same as writing the following, which the compiler is perfectly happy with:

Banana justOneBanana = aBunchOfBananas.SingleOrDefault(); 
like image 50
Yuck Avatar answered Sep 21 '22 11:09

Yuck