2016-05-19 16 views
6

Il caso 1 produce un'eccezione di disallineamento di tipo. Il caso 2 funziona come previsto. Qualcuno ha un'idea del perché? O un modo migliore per convertire da Int32 come oggetto in un Int16?Perché l'operazione di trasmissione fallisce nel caso 1 ma succede nel caso 2?

Caso 1:

var i = (Int16)(object)Int32.Parse("1"); 

Caso 2:

var i = (Int16)Int32.Parse("1"); 
+1

vedere http://stackoverflow.com/questions/9741788/why-does-this-cast-from-short-to-int-fail e https://blogs.msdn.microsoft.com/ericlippert/2009/ 03/19/rappresentazione-e-identità/ – filhit

+0

@filhit. grazie per le referenze eccellenti. la SO è vicina a ciò che ha causato questa domanda. I collegamenti aiutano a rispondere perché. –

+1

@GregBogumil Perché diavolo non usi semplicemente 'Int16.Parse (" 1 ");'? – Mikanikal

risposta

11

La causa è il fatto che in C# l'operatore cast esplicito ha due significati diversi:

  • Il rappresentazione preservano significato è: "So che questo oggetto è sempre di tipo T, anche se il compilatore non ha potuto dimostrarlo staticamente - per favore lascia che lo usi come T invece di qualcosa di più generale ".
  • Il rappresentazione cambia significato è: "So che questo oggetto non è di tipo T, ma c'è una conversione a trasformarlo in T e mi piacerebbe che la conversione da eseguire".

Quindi la ragione che stai ricevendo due comportamenti diversi è che si sta utilizzando ciascuno dei diversi significati di cui sopra rispettivamente:

  • Il tuo primo frammento dice: "So che questo objectè sicuramente un boxed Int16 e mi piacerebbe usarlo come tale ". Ma dal momento che è in realtà un Int32 scatolato, si ottiene un'eccezione di mancata corrispondenza di tipo.
  • Il secondo snippet dice: "So che questo Int32non è sicuramente un Int16, ma mi piacerebbe convertirlo in uno".

In altre parole, unboxing funziona solo se si tenta di annullare l'iscrizione al tipo originale. According to Eric Lippert, il motivo è che è stato semplicemente troppo poco pratico implementarlo in modo che potesse annullare l'accesso e convertire in un'unica operazione.

+0

Ottimo articolo di Eric Lippert. – Lithium

+0

le cose sono sempre molto più semplici all'esterno del framework. A quanto pare, una volta unboxed, un controllo del tipo potrebbe portare alla chiamata di conversione in corso. Questo è il mio commento dopo aver considerato l'articolo solo per un paio di minuti. Mi aspetto che ci siano numerose insidie ​​lungo quel percorso che sono meno desiderabili del comportamento attuale. –

3

Come Damian correttamente commentato, mi sbagliavo. Il problema non era la conversione, il problema risiede nell'operazione di unboxing. Permette di rimuovere unbox da un oggetto dello stesso tipo dal quale era originariamente inserito.

int > object > int ok, int > object > short non lo è e così è short > object > int.

Questo funzionerà solo se lo int è stato prima convertito in un breve, in questo modo: int > short > object > short va bene.

Questo caso particolare viene persino utilizzato in un unboxing sample on MSDN.

+0

Sto eseguendo il caso 1 in Visual Studio 2012 e si compila senza errori. –

+1

Compila ma non esegue. –

+0

Stavo cercando di trovare dove sono state definite queste conversioni. Ti capita di sapere dove? Mi piacerebbe dare un'occhiata. – Nasreddine

2

Nel primo caso il vostro stanno cercando di unbox un Int32 valore digitato in un campo Int16 digitato, che vi dà l'eccezione di tipo non corrispondente in quanto non v'è alcuna conversione implicita a disposizione per lanciare object-Int32.

Nel secondo caso è possibile trasmettere direttamente un Int32 a un Int16. Dal momento che questo è un cast diretto qui avrai il vantaggio di implicit type conversion (see this MSDN article for a more detailed explanation).

Problemi correlati