7

C# 接受以下内容:

object o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

但不是

String o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

我只是想知道asC# 中关键字的行为。

与 Java 相同,这将失败:

Object test1 = "hello";
Integer test2 = (Integer) test1;
String test3 = "hello";
Integer test4 = (Integer) test3; //compilation error
4

5 回答 5

18

编译器知道一个字符串永远不可能是一个int?,所以它会告诉你。这并不意味着它int?没有用。您尝试的用例与正常用例相去甚远。正常的是“我想表示一个整数以及该值丢失/未知的可能性”。为此,int?效果非常好。

为什么你希望你的原始代码能够工作?为什么会有帮助?

请注意,您可以使用as可空类型进行拆箱:

object o = "hello";
int? i = o as int?;

if (i == null)
{
    // o was not a boxed int
}
else
{
    // Can use i.Value to recover the original boxed value
}

编辑:看到您的评论后,您不会as用来解析事物。您可能想使用int.TryParse

string text = "123":
int value;
if (int.TryParse(text, out value))
{
    Console.WriteLine("Parsed successfully: {0}", value);
}
else
{
    Console.WriteLine("Unable to parse text as an integer");
}

如果您确定该字符串是一个整数(否则就是一个错误),那么您可以使用int.Parse

int value = int.Parse(text);

如果解析失败,这将引发异常。

另请注意,这两种方法都允许您指定格式提供程序(通常是文化信息),它允许您表达数字在该格式中的表示方式(例如千位分隔符)。

编辑:在回答您的新问题时,编译器会阻止这种情况,因为它知道字符串不可能是装箱的 int - 转换永远不会成功。当它只知道原始值是一个对象时,它可能会成功。

例如,假设我对你说,“这是一个形状:它是正方形吗?” 这是一个明智的问题。问它是有道理的:不看形状就无法判断。

然而,如果我说:“这是一个三角形:它是一个正方形吗?” 那么你就有理由当着我的面笑,因为三角形不可能是正方形——这个问题没有意义。

于 2009-05-20T13:39:16.640 回答
2

诠释?表示可以为空的整数类型,而不是可以包含任何其他类型变量的 int。

如果你想要一个可以包含 int 或字符串的变量类型,你必须使用一个对象,或者我想是一个字符串,然后过着充满类型转换的生活。不过,我不知道你为什么要这样做。

诠释?允许您存储任何整数值或空值。当说“这个人下了多少订单”这个问题的答案合法地是“我不知道”而不是订单数量时,这很有用,或者为零,这将是“我知道这个人从来没有下了订单”。

于 2009-05-20T13:37:42.430 回答
1

我想补充一些进一步的信息。

另一种情况,为什么强制转换无效并且编译器在编译时抛出错误是System.String被标记为seal。因此编译器知道System.String从哪些类型继承,以及您可以使用as运算符将字符串转换为哪些类型。

由于关键字sealed,编译器还知道您不能从System.String继承来添加功能或实现一些额外的接口。

下面的代码是一个示例,编译器会在编译时抛出以下错误

无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“SealedClass”转换为“ICastToInterface”

public class UnsealedClass {
  // some code
}

public sealed class SealedClass {
  // some code
}

public interface ICastToInterface {
  // some code
}

public class Test {

  public Test() {
    UnsealedClass unsealedClass = new UnsealedClass();

    SealedClass sealedClass = new SealedClass();

    ICastToInterface unsealedCast = unsealedClass as ICastToInterface;  // This works fine

    ICastToInterface sealedCast = sealedClass as ICastToInterface; // This won´t compile, cause SealedClass is sealed
  }
}
于 2009-06-25T06:02:28.893 回答
0

但您可以检查 null 的值并将其设置为 null。

int? blah;
if (blah == null)
{}
于 2009-05-20T13:38:33.457 回答
0

诠释?是一个可为空的整数,它与强制转换和 as 关键字无关。"String" 是一个字符串类型的对象,它不能转换为 int(可空或不可空)。

as 关键字实际上与使用方括号进行强制转换相同,只是它不会返回错误,它将对象设置为 null:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

第一个示例的工作原理是分配给 o 的对象是 int。

现在考虑:

string i = "MyString";

object o = MyString;

 int j = (int)o //unboxing raises exception

 int j = o as int; //raises compilation Error as int is not nullable
 int? j = o as int?; /// o == null

我希望这有助于解释这两个概念之间的区别。

理查德

于 2009-05-20T13:52:52.960 回答