C# 无法将类型“string”转换为“int”?通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/887943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 08:31:42  来源:igfitidea点击:

cannot convert type 'string' to 'int?' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion or null type conversion

c#inttype-conversion

提问by

C# accepts the following:

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
}

But not

但不是

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
}

I'm just wondering about the behaviour of the keyword asin C#.

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

The same as in Java this would fail:

与在 Java 中一样,这将失败:

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

采纳答案by Jon Skeet

The compiler knows that a string can never be an int?so it tells you that. That doesn't mean that int?isn't useful. Your attempted use case is far from the normal one. The normal one is "I want to represent an integer and the possibility that the value is missing/unknown". For that, int?works extremely well.

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

Why would you expectyour original code to work? Why would it be helpful?

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

Note that you canuse aswith nullable types, for unboxing:

请注意,您可以使用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
}

EDIT: Having seen your comment, you don't use asto parse things. You probably want to use int.TryParse:

编辑:看到您的评论后,您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");
}

If you're sure the string is meant to be an integer (i.e. it's a bug otherwise) then you can just use int.Parse:

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

int value = int.Parse(text);

That will throw an exception if the parsing fails.

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

Note also that both of these methods allows you to specify a format provider (usually a culture info) which allows you to express how numbers are expressed in that format (e.g. thousands separators).

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

EDIT: In answer to your new question, the compiler prevents this because it knows a string can't possiblybe a boxed int - the conversion will never ever succeed. When it only knows that the original value is an object, it mightsucceed.

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

For instance, suppose I said to you, "Here's a shape: is it a square?" That's a sensible question. It's reasonable to ask it: you can't tell without looking at the shape.

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

If, however, I said: "Here's a triangle: is it a square?" Then you'd be reasonably entitled to laugh in my face, as a triangle can't possibly be a square - the question doesn't make sense.

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

回答by kscott

int? means a nullable integer type, not an int that could contain any other type of variable.

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

If you want a variable type that could contain an int or a string, you'd have to use an object, or a string I suppose, and then live a life filled with type casting. I don't know why you would want to do that, though.

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

int? allows you to store any integer value, or a null value. Which is useful when say the answer to the question "How many orders has this person placed" is legitimately "I don't know" instead of a number of orders, or zero which would be "I know for a fact this person has never placed an order".

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

回答by CSharpAtl

but you can check the value of null and set it to null.

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

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

回答by Richbits

int? is a nullable integer, it has nothing to do with casting and the as keyword. "String" is a string type object, which is not convertible to an int (nullable or non-nullable).

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

The as Keyword is virtually the same as casting using brackets except it will not return an error, it will set the object to null:

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

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

This first example works as the object assigned to o is an int.

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

Now consider:

现在考虑:

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

I hope that that helps to explain the difference between the two concepts.

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

Richard

理查德

回答by Jehof

I want to add some further information.

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

An other case, why the cast is invalid and the compiler throws an error on compilation is, that System.Stringis marked as sealed. So the compiler knows from which types System.Stringinherites and to which types you can cast the string using the as-operator.

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

Due to the keyword sealed, the compiler also knows that you cannotinherit from System.Stringto add functionality or implement some additional interfaces.

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

The code below is an example and the compiler will throw the following error on compilation

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

Cannot convert type 'SealedClass' to 'ICastToInterface' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“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
  }
}