no se puede convertir tipo 'cadena' a 'int?' a través de una conversión de referencia, la conversión de boxeo, la conversión unboxing, conversión de envoltura o de conversión de tipo nulo

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

  •  23-08-2019
  •  | 
  •  

Pregunta

C # acepta las siguientes:

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
}

Pero no

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
}

me pregunto sobre el comportamiento de la palabra clave as en C #.

Al igual que en Java este fracasarían:

Object test1 = "hello";
Integer test2 = (Integer) test1;
String test3 = "hello";
Integer test4 = (Integer) test3; //compilation error
¿Fue útil?

Solución

El compilador sabe que una cadena no puede ser nunca un int? por lo que le dice eso. Eso no quiere decir que int? no es útil. Su intento de caso de uso está muy lejos de la normal. La normal es "Quiero representar un entero y la posibilidad de que el valor no se encuentra / desconocido". Por eso, int? funciona muy bien.

¿Por qué esperar su código original para trabajar? ¿Por qué sería útil?

Tenga en cuenta que puede as uso con tipos anulables, por unboxing:

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: Después de haber visto su comentario, usted no utiliza as para analizar las cosas. Es posible que desee utilizar 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");
}

Si está seguro de la cadena está destinado a ser un número entero (es decir, se trata de un error de otro tipo) a continuación, puedes utilizar int.Parse :

int value = int.Parse(text);

Eso hará una excepción si falla el análisis.

Tenga en cuenta también que estos dos métodos permite especificar un proveedor de formato (por lo general una información cultural), que le permite expresar cómo los números se expresan en ese formato (por ejemplo, separadores de miles).

EDIT: En respuesta a su pregunta nueva, el compilador lo impide porque conoce una cadena no puede posiblemente haber una caja int - La conversión nunca tienen éxito. Cuando sólo se sabe que el valor original es un objeto, podría tener éxito.

Por ejemplo, supongamos que te dije, "Aquí hay una forma: ¿es una plaza" Esa es una pregunta sensata. Es razonable pedir que:. No se puede decir sin tener en cuenta la forma

Si, sin embargo, le dije: "Aquí hay un triángulo: ¿es una plaza" Entonces sería razonable derecho a reírse en mi cara, como un triángulo no puede ser un cuadrado -. La pregunta no tiene sentido

Otros consejos

int? significa un tipo entero anulable, no un int que podría contener cualquier otro tipo de variable.

Si desea un tipo variable que podría contener un entero o una cadena, que tendría que utilizar un objeto, o una cadena supongo, y luego vivir una vida llena de tipos. No sé por qué querría hacer eso, sin embargo.

int? le permite guardar cualquier valor entero, o un valor nulo. Que es útil cuando dicen que la respuesta a la pregunta "¿Cuántos pedidos ha colocado a esta persona" es legítimamente "No sé" en lugar de una serie de órdenes, o cero, lo que sería "Sé que es un hecho de que esta persona no tiene puesto una orden".

Quiero añadir alguna información adicional.

Un otro caso, ¿por qué el reparto no es válido y el compilador genera un error en la compilación es, que System.String está marcado como sellados . Por lo que el compilador sabe de qué tipos System.String inherites y para qué tipos puede convertir la cadena utilizando el como -operator.

Debido a la palabra clave sellados , el compilador también sabe que no pueden heredar de System.String para añadir funcionalidad o implementar algunas interfaces adicionales .

El código siguiente es un ejemplo y el compilador va a lanzar el siguiente error en la compilación

  

No se puede convertir tipo 'SealedClass' a   'ICastToInterface' a través de una referencia   la conversión, la conversión de boxeo,   conversión unboxing, envoltura   conversión, o tipo nulo conversión

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
  }
}

pero se puede comprobar el valor de nulo y configurarlo en nulo.

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

int? es un número entero anulable, no tiene nada que ver con la fundición y como palabra clave. "Cadena" es un objeto de tipo de cadena, que no es convertible a un int (anulable o no anulable).

El como palabra clave es prácticamente la misma que la colada usando los soportes excepto que no devolverá un error, se establecerá el objeto a null:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

Este primer ejemplo funciona como el objeto asignado a O es un int.

Ahora considere:

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

Espero que eso ayuda a explicar la diferencia entre los dos conceptos.

Richard

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top