Оператор as
отличается от оператора приведения. Этот блог объясняет:
http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-cast-syntax-and-using-the-code-as-code-operator.aspx
Он только «забрасывает» между типами в одной иерархии, в основном следуя идее «есть». decimal?
- это не double?
, но компилятор может заставить вас думать, что это возможно, когда вы (decimal?)myDouble;
, потому что он явно использует его для потери информации. Оператор as
не делает этого за вас и, следовательно, завершается ошибкой.
Обновление: вы спрашиваете, почему произошла ошибка компилятора, а не нулевой результат. Это связано с тем, что оператор as
никогда не сможет получить double?
до decimal?
. Попробуйте:
string s = "";
MyClass f = s as MyClass;
Из коробки это не работает, потому что компилятор это знает. Лучше получить ошибку компилятора, потому что он никогда не сможет работать в своем текущем состоянии.
При обычном использовании оператор as
может использоваться для перенаправления базовых типов приведения в производные типы, если тип на самом деле является тем типом, о котором вы думаете. Однако тип может быть другим производным типом (компилируется):
MyBase b = new MyDerived1();
MyDerived2 d = b as MyDerived2();
Хотя технически компилятор может знать это (в некоторых ситуациях), если он этого не делает, он отвечает нулем, если приведение не удается.
Я уверен, что кто-то собирается прийти и сказать мне, как я неправ: -)