8
votes

C # - Problèmes avec la boxe / le non-boxing / typé des intensions. Je ne comprends pas

J'ai du mal à comprendre cela. Considérez l'exemple suivant:

protected void Page_Load(object sender, EventArgs e)
{
    // No surprise that this works
    Int16 firstTest = Convert.ToInt16(0);
    int firstTest2 = (int)firstTest;

    // This also works
    object secondTest = 0;
    int secondTest2 = (int)secondTest;

    // But this fails!
    object thirdTest = Convert.ToInt16(0);
    int thirdtest2 = (int)thirdTest;  // It blows up on this line.
}


1 commentaires

INT16 est en fait un court. Donc, je pense que vous pouvez remplacer 'int16 firstTest = convert.toint16 (0);' avec 'int16 firsttest = 0s;'


3 Réponses :


12
votes

Unboxing vérifie le type exact comme expliqué dans le Documentation .

Unboxing est une conversion explicite de l'objet type sur une valeur type ou à partir d'un type d'interface à un type de valeur qui implémente la interface. Une opération de non-interoxing est composée de: p>

  • Vérification de l'instance d'objet pour vous assurer qu'il s'agit d'une valeur encastrée de le type de valeur donné. p> li>

  • Copier la valeur de l'instance dans la variable de type valeur. P> li> ul> blockquote>

    Comme vous pouvez le voir, la première étape consiste à vérifier que l'instance d'objet correspond au type cible. p>

    citation de la documentation: P>

    Pour le déclenchement des types de valeur pour réussir le temps d'exécution, l'article étant Unboxed doit être une référence à un objet qui a été créé précédemment en boxant une instance de ce type de valeur. Tenter de NUBLY NULL provoque une nullreferenceException. Tenter de créer une référence une référence à un Le type de valeur incompatible provoque une exception invalide. P> blockQuote>

    Pour résoudre cette erreur, assurez-vous que le type correspond auquel vous correspondez avant de tenter de la BOXE: P>

    object thirdTest = Convert.ToInt16(0);
    short thirdtest2 = (short)thirdTest;  
    


1 commentaires

Ou la boîte à la boîte avec le type correct, puis jeté sur votre type souhaité. int tierstest2 = (int) (court) tierstest;



9
votes

Qu'est-ce qui se passe est exactement ce qu'il dit.

Dans le premier cas, vous avez une courte durée, non incorrectée, que vous utilisez ensuite explicitement à un int. Il s'agit d'une conversion valide que le compilateur sait comment faire, de sorte que cela fonctionne. P>

Dans le second cas, vous avez un INT, Boxed, qui vous attribuent à un int. Il s'agit d'une simple boîteboxing d'un entier, qui est également valide, de sorte qu'il fonctionne. P>

Dans le troisième cas, vous avez un court, encadré, qui essayez-vous de la BOX dans une variable qui n'est pas une courte . Ce n'est pas une opération valide: vous ne pouvez pas faire cela en une étape. Ce n'est pas un problème rare, non plus: si vous utilisez, par exemple, un sqldatareader code> contenant une colonne code> Smallint code>, vous ne pouvez pas faire: P>

    object thirdTest = Convert.ToInt16(0);
    int thirdTest2 = Convert.ToInt32(thirdTest);
    int thirdTest3 = (int)(short)thirdTest;


0 commentaires

4
votes

int16 est une solution fantaisie pour écrire court ; Il n'y a pas de boxe / une boîte de box donnant là-bas, juste la conversion claire simple entre les entiers 16 bits et 32 ​​bits.

Les secondes boîtes de cas et les boîtes de non-cas au même type, qui est autorisée: type de valeur int est enveloppé dans un objet , puis est non emballé.

Le troisième cas essaie de la Boîte à un type différent ( int au lieu de court ) qui n'est pas autorisé.


0 commentaires