Est-ce que la boxe / décomposition est-elle mise en œuvre par une liaison tardif ou anticipée (c'est-à-dire au moment de l'exécution ou à la compilation)?

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

  •  29-10-2019
  •  | 
  •  

Question

Par exemple:

int i=10;
object o = i; //late or early??

De même,

object o = "11";
int i = (int)o;//late or early??
Était-ce utile?

La solution

La boxe et le déballage sont-ils mis en œuvre via une liaison tardive ou anticipée? Autrement dit, la liaison est-elle effectuée au moment de l'exécution ou de la compilation?

Je suis un peu confus par la question. «Reliure» est généralement utilisé pour désigner le résultat d'une sorte d'analyse. "Early binding" signifie généralement qu'un nom a été associé à un emplacement de méthode au moment de la compilation; "late binding" associe le nom au slot lors de l'exécution. Qu'entendez-vous par "contraignant" ici dans le contexte de la boxe?

Je suppose que vous voulez dire que la liaison tardive entre en jeu uniquement pour les appels de méthode et de méthode et non pour les opérations d'affectation / conversions de type. Pour implémenter la liaison dynamique, nous faisons référence aux objets dérivés avec des variables de classe de base.

Ce n'est pas exactement ce que je voulais dire; J'utilisais des appels de méthode comme exemple canonique qui illustre la différence entre la liaison précoce et tardive. Je vois mieux votre point maintenant; l'analyse qui détermine précisément comment une conversion est effectuée peut également être effectuée au moment de l'exécution ou de la compilation et est donc en un sens également une forme de "liaison tardive" ou de "liaison anticipée".

Prenons comme exemple cette conversion:

int x = Whatever();
short y = (short)x;

Cette conversion explicite est entièrement "liée" au moment de la compilation. Le compilateur sait que l'opérande est un int, que le type cible est court, que la conversion sera effectuée en tronquant les quatre octets int en deux octets courts. La conversion est bien sûr effectuée au moment de l'exécution.

Rendons les choses un peu moins claires:

int x = Whatever();
short y = checked((short)x);

La conversion explicite est à nouveau liée au moment de la compilation. Nous savons comment l'opération sera effectuée. Mais nous savons aussi que lors de l'exécution, la valeur int sera vérifiée pour s'assurer qu'elle s'insère dans un court .

Est-ce que cela compte comme une "reliure tardive" dans votre livre? Une partie de l'analyse est effectuée au moment de la compilation, mais une partie de l'analyse est effectuée au moment de l'exécution.

Considérons maintenant la boxe:

int x = Whatever();
object q = x;

Ceci est entièrement analysé au moment de la compilation. Le compilateur sait que q est un objet et x est un int, et par conséquent, il devra émettre des instructions qui encadrent l'int à l'exécution.

Et le déballage?

int x = Whatever();
object q = x;
int y = (int)q;

Quelle analyse est effectuée au moment de la compilation? Tout ce que nous savons au moment de la compilation, c'est qu'il s'agit d'une conversion de déballage. La vérification de type proprement dite est effectuée au moment de l'exécution. Est-ce une forme de "liaison tardive" car une vérification de type est effectuée à l'exécution, selon votre définition de liaison tardive?

Et ça?

int x = Whatever();
object q = x;
int y = (short)q;

Cela lève une exception lors de l'exécution. Au moment de la compilation, nous savons qu'il s'agit d'une conversion de déballage. Au moment de l'exécution, nous ne faisons pas de «liaison tardive» pour dire «hé, j'ai un int en boîte, laissez-moi comprendre comment le convertir en un court sans boîte». Au contraire, nous disons "nous essayons de déballer un int en court; lancer une exception". Un T encadré ne peut être déballé que vers un T ou un T. Nullable

Alors, le déballage est-il "lié tôt" ou "tardif"? Il est lié au début dans le sens où nous savons au moment de la compilation qu'il s'agit d'une conversion de déballage. Il est lié tardivement dans le sens où nous effectuons une vérification de type au moment de l'exécution. Il n'est pas lié tardivement dans le sens où nous ne refaisons pas au moment de l'exécution l'analyse de type qui aurait été effectuée pour une conversion int-to-short au moment de la compilation.

Et ça?

int x = Whatever();
object q = x;
int y = Convert.ToInt16(q);

ou

int x = Whatever();
dynamic q = x;
int y = (int)q;

Maintenant, nous faisons toutes ces analyses lors de l'exécution; dans les deux cas, nous effectuons l'analyse de type de q au moment de l'exécution, déterminons que q est un entier encadré et "lient tard" la conversion.

Est-ce que tout est clair? Il est difficile de répondre à votre question car elle est un peu vague concernant précisément ce que vous entendez par «liaison tardive» d'une conversion. Quelle partie de l'analyse vous "lie"?

Autres conseils

La boxe est intégrée dans les instructions IL au moment de la compilation si c'est ce que vous recherchez.

Si vous essayez de déballer dans un type autre que le type d'origine, une exception serait levée.Ex # 1, il arrive juste de boxer implicitement (type valeur en type ref cast).Ex # 2 Un casting invalide explose au moment de l'exécution.

Je ne sais pas à quel point la reliure est précoce ou tardive.

Le compilateur émettra des instructions de boxe que vous pourrez voir dans l'IL.Code donné

int item = 10;
object obj = item;
item = (int)obj;

Vous allez compiler jusqu'à quelque chose comme

IL_0000:  ldc.i4.s    0A 
IL_0002:  stloc.0     
IL_0003:  ldloc.0     
IL_0004:  box         System.Int32
IL_0009:  stloc.1     
IL_000A:  ldloc.1     
IL_000B:  unbox.any   System.Int32
IL_0010:  stloc.0     

Dans la deuxième version, ça va exploser.Un objet de type chaîne ne peut pas être converti en entier.

Le C # compile les instructions exécutées au moment de l'exécution.

La boxe implique un coût d'exécution (non inconsidérée);La boxe et le décoffrage peuvent provoquer des erreurs d'exécution (comme votre exemple "int i= (int) o" illustre).

"La liaison tardive" vs "la liaison précoce" implique quelque chose est "dynamique" (par exemple, la liaison d'exécution de la méthode virtuelle de certains objets).Dans ce cas, la boxe est "fixe".Donc, je suppose que vous pourriez dire que c'est "une liaison anticipée".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top