无法将'string'类型转换为'int?'通过引用转换,装箱转换,拆箱转换,换行转换或空类型转换

时间:2009-05-20 13:36:30

标签: c# int type-conversion

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
}

我只是想知道关键字as在C#中的行为。

与Java相同,这将失败:

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

5 个答案:

答案 0 :(得分: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");
}

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

int value = int.Parse(text);

如果解析失败,那将抛出异常。

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

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

例如,假设我对你说,“这是一个形状:它是一个正方形吗?”这是一个明智的问题。问它是合理的:没有看到形状你就无法分辨。

但是,如果我说:“这是一个三角形:它是一个正方形吗?”然后你有理由在我的脸上笑,因为三角形不可能是一个正方形 - 这个问题没有意义。

答案 1 :(得分:2)

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

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

INT?允许您存储任何整数值或空值。当说“这个人放了多少个订单”这个问题的答案是合法的“我不知道”而不是一些订单,或者说“我知道这个人从来没有这样的事实”时,这很有用下订单“。

答案 2 :(得分:1)

我想补充一些其他信息。

另一种情况是,为什么转换无效且编译器在编译时抛出错误, System.String 被标记为密封。因此,编译器知道 System.String 继承哪些类型,以及使用作为 -operator将字符串转换为哪些类型。

由于关键字密封,编译器还知道无法继承 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
  }
}

答案 3 :(得分:0)

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

int? blah;
if (blah == null)
{}

答案 4 :(得分:0)

INT?是一个可以为null的整数,它与cast和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

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

理查德