Когда вы говорите Y y = (Y)x;
, это приведение говорит компилятору: "Поверьте мне, что бы ни было x
, во время выполнения его можно привести к Y
, так что просто сделайте это, хорошо?"
Но когда вы говорите
List<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
компилятор может посмотреть определения для каждого из этих конкретных классов (Banana
и List<Banana>
) и увидеть, что не определено static explicit operator Banana(List<Banana> bananas)
(помните, явное приведение должно быть определено в любом типе, который приводится или тип, к которому производится приведение, это из спецификации, раздел 17.9.4). Во время компиляции он знает, что то, что вы говорите, не может быть правдой. Поэтому он кричит на тебя, чтобы ты перестал лгать.
Но когда вы говорите
IEnumerable<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
хорошо, теперь компилятор не знает. Вполне может случиться так, что независимо от того, что aBunchOfBananas
окажется во время выполнения, его конкретный тип X
мог бы определить static explicit operator Banana(X bananas)
. Таким образом, компилятор доверяет вам, как вы и просили.