31

除了和之间的常规无聊差异Cast之外As

  • 如果我知道苹果水果,所以我可以使用(Fruit)apple- 如果它不是,它会引发异常
  • as value可以检查 null 以查看是否成功[不会抛出异常...]

但是我一直在阅读@EricLippert关于此的文章,并且有一个关于 Nullable Value Types 的很​​好的示例:

short? s = (short?)123;
int? i = s as int?;

不会编译...

无法转换类型“短?” 到'int?通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换

美好的。

那么为什么这样:

    short? s = (short?)123;
    int? i = (int?)s;

是否编译?(出乎所有人的意料!我知道s不是 int? - 它应该会爆炸,但它不是......)

这里的 Cast 检查应该比前一个例子(它去 Bang)更致命

问起这个话题,我感觉很糟糕。

提前致谢。

4

5 回答 5

27

在您的第一个示例中,as操作员尝试将对象s用作int?. 由于int?不在 的继承链中的任何位置short?,因此此操作失败。

在您的第二个示例中,您实际上是在int? i使用 from 的值创建一个新的short? s。这是一个更慷慨的操作,因为它不必保留s左侧的原始对象。

这里的重点as是不允许做任何不保留对象身份的事情。显式转换可以。

以下是 C# 标准对(int?)表单工作方式的说明:

6.1.4 隐式可空转换

对不可空值类型进行操作的预定义隐式转换也可以与这些类型的可空形式一起使用。对于从不可空值类型 S 转换为不可空值类型 T 的每个预定义隐式标识和数值转换,存在以下隐式可空转换:

· 从 S 的隐式转换?到T?。

· 从 S 到 T? 的隐式转换。

基于从 S 到 T 的基础转换对隐式可空转换的评估如下进行:

· 如果可以为空的转换来自 S?到 T?:

o 如果源值为 null(HasValue 属性为 false),则结果为 T? 类型的 null 值。

o 否则,转换被评估为从 S?到 S,然后是从 S 到 T 的基础转换,然后是从 T 到 T 的包装(第 4.1.10 节)。

· 如果可以为空的转换是从 S 到 T?,则转换被评估为从 S 到 T 的基础转换,然后是从 T 到 T? 的换行。

于 2012-04-08T18:55:42.247 回答
4

这个例子:

int? i = (int?)s;

编译器是否因为强制转换是您告诉编译器您知道它无法推断的东西,也就是说,s可以转换为int?.

如果强制转换不成功,您只会在运行时收到异常。

于 2012-04-08T18:55:00.330 回答
0

我认为这是因为在as失败的情况下你会得到一个“有效”的null结果,所以false positive。在第二种情况下,允许强制转换,因为如果失败,它将引发异常。

于 2012-04-08T18:55:26.490 回答
0

原因是int?只是System.Nullable<int>(System.Nullable<T>是类型) 的简写。short 类型定义了对 int 的显式转换,但是System.Nullable<T>没有任何这样的显式转换,因为 T 可以是任何其他值类型。

于 2012-04-08T19:27:42.000 回答
0

我通过反射找到了这个可能的解决方案。这个想法是:

    var notNullableValue = 3;
    var someNullableType = typeof(Nullable<int>);
    var nullableValue = Activator.CreateInstance(someNullableType, new[] { notNullableValue });

In my case I could not use a direct cast because I was using arbitrary Types and Reflection to create an object and fill all properties.

于 2021-10-25T12:34:51.030 回答