Не удается преобразовать тип «строка» в «int?» через конверсию справочника, преобразование бокса, преобразование распаковки, преобразование обертывания или преобразование с нулевым типом

StackOverflow https://stackoverflow.com/questions/887943

  •  23-08-2019
  •  | 
  •  

Вопрос

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 в С#.

Так же, как и в Java, это не удастся:

Object test1 = "hello";
Integer test2 = (Integer) test1;
String test3 = "hello";
Integer test4 = (Integer) test3; //compilation error
Это было полезно?

Решение

Компилятор знает, что строка никогда не может быть int? так это вам об этом говорит.Это не значит, что int? бесполезно.Ваша попытка использования далека от нормальной.Обычный вариант: «Я хочу представить целое число и вероятность того, что значение отсутствует/неизвестно».Для этого, int? работает очень хорошо.

Почему ты ожидать ваш исходный код работает?Почему это может быть полезно?

Обратите внимание, что вы может использовать as с типами, допускающими значение NULL, для распаковки:

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 - преобразование никогда не будет успешным.Когда он знает только, что исходное значение является объектом, он мощь преуспевать.

Например, предположим, что я сказал вам: «Вот форма:это квадрат?» Это разумный вопрос.Разумно спросить:Вы не можете сказать, не глядя на форму.

Если бы я сказал:«Вот треугольник:это квадрат?» Тогда вы имеете полное право смеяться мне в лицо, поскольку треугольник не может быть квадратом — вопрос не имеет смысла.

Другие советы

инт?означает целочисленный тип, допускающий значение NULL, а не int, который может содержать переменную любого другого типа.

Если вам нужен тип переменной, который может содержать int или строку, вам придется использовать объект или, я полагаю, строку, а затем жить жизнью, наполненной приведением типов.Хотя я не знаю, почему вы хотите это сделать.

инт?позволяет хранить любое целочисленное значение или нулевое значение.Это полезно, когда, скажем, ответом на вопрос «Сколько заказов разместил этот человек» законно является «Я не знаю» вместо количества заказов или ноль, что было бы «Я точно знаю, что этот человек никогда не делал этого». сделал заказ».

Я хочу добавить дополнительную информацию.

Другой случай, почему приведение недопустимо и компилятор выдает ошибку при компиляции, заключается в том, что Система.Строка отмечен как запечатанный.Таким образом, компилятор знает, из каких типов Система.Строка наследует и к каким типам можно привести строку с помощью как-оператор.

Из-за ключевого слова запечатанный, компилятор также знает, что вы не могу наследовать от Система.Строка для добавления функциональности или реализации каких-то дополнительных интерфейсов.

Код ниже является примером, и компилятор выдаст следующую ошибку при компиляции.

Невозможно преобразовать тип «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
  }
}

но вы можете проверить значение null и установить для него значение null.

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

инт?— это целое число, допускающее значение NULL, оно не имеет ничего общего с приведением типов и ключевым словом as.«Строка» — это объект строкового типа, который нельзя преобразовать в целое число (с нулевым или ненулевым значением).

Ключевое слово as практически аналогично приведению с использованием скобок, за исключением того, что оно не возвращает ошибку, а устанавливает для объекта значение null:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

Этот первый пример работает, поскольку объект, присвоенный o, является целым числом.

Теперь рассмотрим:

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

Я надеюсь, что это поможет объяснить разницу между этими двумя понятиями.

Ричард

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top