Comment le système System.Boolean de mscorlib évite-t-il les cycles de mise en page des structures?


10

Le code System.Booleansource du site Web de référence indique que les instances de struct Booleanne contiennent qu'un seul boolchamp private bool m_value::

https://referencesource.microsoft.com/#mscorlib/system/boolean.cs,f1b135ff6c380b37

namespace System {

    using System;
    using System.Globalization;
    using System.Diagnostics.Contracts;

    [Serializable]
    [System.Runtime.InteropServices.ComVisible(true)]
    public struct Boolean : IComparable, IConvertible
#if GENERICS_WORK
        , IComparable<Boolean>,  IEquatable<Boolean>
#endif
    {
      private bool m_value;

      internal const int True = 1; 
      internal const int False = 0; 

      internal const String TrueLiteral  = "True";
      internal const String FalseLiteral = "False";

      public static readonly String TrueString  = TrueLiteral;
      public static readonly String FalseString = FalseLiteral;
}

Mais j'ai remarqué que ...

  • boolest un alias du langage C # pour System.Boolean.
  • Le type est struct Booleanqui est un type de valeur, ce qui signifie qu'il ne peut pas se contenir en tant que champ .
  • ... mais ce code compile probablement.
  • Je comprends que lorsque l' -nostdliboption de compilateur est défini devez fournir vos propres essentielles définitions de type aiment System.String, System.Int32, System.Exception- qui est la seule différence.
  • Le code source publié ne contient aucun autre attribut spécial comme [MethodImpl( MethodImplOptions.InternalCall )].

Alors, comment ce code se compile-t-il?


1
C'est une démonstration décente que l'hypothèse commune "c'est un pseudonyme" est un modèle mental brisé. boolest un mot - clé du langage C #. Le compilateur et le runtime ont beaucoup de connaissances intégrées sur le type et n'ont pas besoin d'aide de System.Boolean. Les déclarations dans mscorlib pour les types de valeur primitifs correspondent à la représentation encadrée du type.
Hans Passant

Réponses:


3

Réponse courte : c'est un cas particulier, relatif à la boxe de type et à leur représentation sous-jacente. Ces types sont bien connus du compilateur et, en tant que tels, sont traités légèrement différemment par les parties centrales de l'exécution et l'optimiseur du compilateur / JIT par rapport aux types normaux.


Étant donné que cela est profondément enfoui dans l'implémentation d'exécution, je suppose que la spécification du langage n'entrerait pas dans les détails d'implémentation d'exécution spécifiques. Je ne sais pas si c'est une réponse suffisamment satisfaisante mais je pense que dans ce cas particulier, le booltype reste non encadré et existe donc en tant que type de valeur brute dans le cadre de la structure.

La sémantique du boxing et du unboxing des types de valeurs est intentionnellement opaque pour faciliter l'utilisation du langage. Dans ce cas, la Booleanstructure elle-même semble s'appuyer sur des règles de boxe spécifiques à l'implémentation pour implémenter la sémantique réelle telle que:

  // Determines whether two Boolean objects are equal.
  public override bool Equals (Object obj) {
    //If it's not a boolean, we're definitely not equal
    if (!(obj is Boolean)) {
      return false;
    }

    return (m_value==((Boolean)obj).m_value);
  }

Je crois en ce qui précède, une structure encadrée représentant un type booléen est d'abord vérifiée par type, puis décomposée et la boolvaleur interne directement comparée. Contrairement à un type encadré, qui peut être un pointeur étiqueté ou une structure réelle avec certaines informations de type d'exécution, les types non encadrés sont traités comme des données réelles.

Je crois qu'en interne, si un booléen devait être encadré pour être transmis car System.Object(en raison de l'effacement de type ou où aucune optimisation ne serait possible), vous vous retrouveriez avec quelque chose dans le sens de cela pour truequelles cases la valeur 1.

ldc.i4.1
box        [mscorlib]System.Boolean

Ainsi, bien qu'à un niveau élevé boolet System.Booleansemblent identiques et peuvent être optimisés de la même manière, dans ce cas particulier au cours de l'exécution, les distinctions entre les versions en boîte et non en boîte de boolsont directement exposées. De même, un non encadré boolne peut pas être comparé à celui System.Objectqui est intrinsèquement un type encadré. Cette réponse concernant la nécessité de la boxe / unboxing va beaucoup plus loin dans l'explication du principe lui-même.

Dans les langages d'exécution, les implémentations d'exécution doivent généralement être exemptées de certaines règles en ce qui concerne certaines fonctionnalités principales d'exécution, cela est certainement vrai pour Java et d'autres langages basés sur JVM. Bien que je ne connaisse pas aussi bien le CLR, je pense que le même principe s'applique ici.

Bien que cette question sur le fait que «bool» soit un alias de type pour «System.Boolean» couvre essentiellement les cas d'utilisation générale, lorsque vous vous rapprochez de l'implémentation d'exécution, le dialecte de C # devient plus comme «l'implémentation C #», ce qui peut légèrement plier les règles .


J'ai voté pour cela pour votre compréhension - mais je ne peux pas marquer cela comme la réponse acceptée car elle ne fait pas autorité, désolé :(
Dai
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.