使用'as'进行投射 - 为什么这不起作用?

fea*_*net 1 c# ado.net casting type-conversion

也许现在早上太早了,我是个白痴,但我有点困惑....

SqlCommand cmd = new SqlCommand("prc_FooBar", conn));
object obj = cmd.ExecuteScalar();

 // this is fine
decimal? d = (decimal?)(obj as double?);

// this doesn't compile
decimal? d = (obj as double?) as decimal?; 
Run Code Online (Sandbox Code Playgroud)

为什么不编译最后一个版本?

Ada*_*rth 6

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

它只是在同一层次结构中的类型之间"强制转换",基本上遵循"is-a"的想法.A decimal?不是a double?,但是编译器可以诱骗你认为它可以是你的,(decimal?)myDouble;因为它是在显着地为你丢失信息.该as运营商不为你做到这一点,因此失败.

更新:您问为什么存在编译器错误而不是null结果.这是因为as运营商不可能想像得double?decimal?.尝试:

string s = "";
MyClass f = s as MyClass;
Run Code Online (Sandbox Code Playgroud)

开箱即用,这不起作用,因为编译器知道这一点.最好得到一个编译器错误,因为它永远不会在它的当前状态下工作.

在正常使用情况下,as如果类型实际上是您认为的类型,则可以使用运算符将​​转换基类型转发为派生类型.但是,类型可能是另一种派生类型(此编译):

MyBase b = new MyDerived1();
MyDerived2 d = b as MyDerived2();
Run Code Online (Sandbox Code Playgroud)

尽管编译器在技术上可以知道这种情况(在某些情况下),但如果编译器没有,则在演员失败时它会以null响应.

我确定有人会来,告诉我我有多错误:-)