Non in grado di convertire il tipo 'string' a 'int?' tramite una conversione di riferimento, conversione pugilato, unboxing conversione, conversione confezionamento o conversione di tipo nullo

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

  •  23-08-2019
  •  | 
  •  

Domanda

C # accetta il seguente:

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
}

Ma non

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
}

Mi chiedo solo circa il comportamento della parola chiave as in C #.

Lo stesso come in Java questo fallirebbe:

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

Soluzione

Il compilatore sa che una stringa non può mai essere un int? così che dice. Ciò non significa che int? non è utile. Il tuo caso d'uso tentato è lontano da quello normale. Quella normale è: "Voglio rappresentare un intero e la possibilità che il valore è mancante / sconosciuto". Per questo, int? funziona molto bene.

Perché si aspettarsi il codice originale di lavorare? Perché sarebbe utile?

Si noti che è possono uso as con tipi nullable, per 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: Dopo aver visto il tuo commento, non si utilizza as per analizzare le cose. Probabilmente si desidera utilizzare 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");
}

Se sei sicuro la stringa è destinata ad essere un numero intero (cioè si tratta di un bug in altro modo), allora si può semplicemente utilizzare int.Parse :

int value = int.Parse(text);

Che sarà un'eccezione se l'analisi non riesce.

Si noti inoltre che entrambi questi metodi consente di specificare un provider di formato (di solito un Info cultura), che consente di esprimere quanto i numeri sono espressi in quel formato (ad esempio separatori di migliaia).

EDIT: In risposta alla tua nuova domanda, il compilatore impedisce questo perché sa una stringa non può eventualmente essere un int boxed - la conversione sarà mai e poi mai avere successo. Quando si sa solo che il valore originale è un oggetto, è potrebbe avere successo.

Per esempio, supponiamo che ti ho detto, "Qui è una forma:? È una piazza" Questa è una domanda sensata. E 'ragionevole chiedere che:. Non si può dire senza guardare la forma

Se, invece, ho detto: "Ecco un triangolo:? È una piazza" Poi si sarebbe ragionevolmente diritto di ridere in faccia, come un triangolo non può assolutamente essere un quadrato -. La questione non ha senso

Altri suggerimenti

int? : un tipo integer nullable, non un int che può contenere qualsiasi altro tipo di variabile.

Se si desidera un tipo di variabile che potrebbe contenere un int o una stringa, che avrebbe dovuto usare un oggetto o una stringa suppongo, e poi vivere una vita piena di casting di tipo. Non so perché si vuole fare questo, però.

int? Consente di memorizzare qualsiasi valore intero, o un valore nullo. Che è utile quando dicono che la risposta alla domanda "Quanti ordini ha questa persona collocata" è legittimamente "Non lo so" invece di un numero di ordini, o pari a zero, che sarebbe "So per certo questa persona ha mai fatto un ordine".

Voglio aggiungere alcune ulteriori informazioni.

Un altro caso, perché il cast non è valido e il compilatore genera un errore sulla compilation è, che System.String è contrassegnato come sigillato . Quindi il compilatore sa da quali tipi di System.String inherites e per quali tipi si può lanciare la stringa utilizzando il come -operator.

A causa della parola chiave sigillato , il compilatore sa anche che non può ereditare da System.String per aggiungere funzionalità o implementare alcune interfacce aggiuntive .

Il codice che segue è un esempio e il compilatore getteranno il seguente errore di compilazione

  

Non è possibile convertire il tipo 'SealedClass' a   'ICastToInterface' attraverso un riferimento   la conversione, la conversione di pugilato,   conversione unboxing, involucro   conversione o digitare null conversione

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

ma è possibile controllare il valore di null e impostarlo su null.

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

int? è un intero annullabile, non ha nulla a che fare con il casting e come parola chiave. "Stringa" è un oggetto di tipo stringa, che non è convertibile in un int (nullable o non nullable).

Il come parola chiave è praticamente lo stesso di getto con staffe tranne che non restituirà un errore, si imposterà l'oggetto da nulla:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

Questo primo esempio funziona come oggetto assegnato o è un int.

Consideriamo ora:

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

Mi auguro che che aiuta a spiegare la differenza tra i due concetti.

Richard

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top