Как mscorlib `System.Boolean` избегает циклов структурного размещения?

10

Исходный код для System.Booleanвеб-сайта Reference Source утверждает, что экземпляры struct Booleanсодержат только одно boolполе 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;
}

Но я заметил это ...

  • boolявляется С # языка псевдонимом для System.Boolean.
  • Тип struct Booleanявляется значением-типом, что означает, что он не может содержать себя в качестве поля .
  • ... все же этот код предположительно компилируется.
  • Я понимаю , что когда -nostdlibпараметр компилятора установлен вам необходимо предоставить свои собственные основные определения типа нравится System.String, System.Int32, System.Exception- это единственное различие.
  • Опубликованный исходный код не содержит других специальных атрибутов, таких как [MethodImpl( MethodImplOptions.InternalCall )].

Так как этот код компилируется?

Dai
источник
1
Это достойная демонстрация того, что распространенное предположение "это псевдоним" - это сломанная ментальная модель. boolявляется ключевым словом в языке C #. И компилятор, и среда выполнения имеют много встроенных знаний о типе и не нуждаются в помощи от System.Boolean. Объявления в mscorlib для примитивных типов значений соответствуют коробочному представлению типа.
Ганс

Ответы:

3

Краткий ответ : это особый случай, связанный с боксом типов и их базовым представлением. Эти типы хорошо известны компилятору и как таковые обрабатываются основными компонентами среды выполнения и оптимизатором JIT по сравнению с обычными типами.


Поскольку это скрыто в реализации времени выполнения, я бы предположил, что спецификация языка не будет вдаваться в конкретные детали реализации времени выполнения. Я не уверен, что это достаточно удовлетворительный ответ, но я думаю, что в данном конкретном случае boolтип остается неупакованным и, таким образом, существует как необработанный тип значения как часть структуры.

Семантика упаковки и распаковки типов значений намеренно непрозрачна, чтобы упростить использование языка. В этом случае сама Booleanструктура, кажется, полагается на специфические для реализации правила бокса для реализации фактической семантики, такой как:

  // 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);
  }

Я верю в вышесказанное, коробочная структура, представляющая логический тип, сначала проверяется на тип, затем распаковывается и boolсравнивается внутреннее значение. В отличие от типа в штучной упаковке, который может быть теговым указателем или фактической структурой с некоторой информацией о типе среды выполнения, неупакованные типы обрабатываются как фактические данные.

Я считаю, что внутренне, если бы bool нужно было поместить в коробку как System.Object(из-за стирания типа или там, где невозможна оптимизация), вы бы получили что-то вроде этого, для trueкоторого устанавливается значение 1.

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

Таким образом, хотя они находятся на высоком уровне boolи System.Booleanкажутся идентичными и могут быть оптимизированы аналогичным образом, в этом конкретном случае во время выполнения, различия между коробочной и распакованной версиями boolнапрямую выявляются. Похоже, что без коробки boolнельзя сравнить с тем, System.Objectчто по сути является коробочным типом. Этот ответ о необходимости упаковки / распаковки гораздо глубже, чем объяснение самого принципа.

В управляемых языках реализации времени выполнения обычно должны быть освобождены от определенных правил, когда речь идет о некоторых основных функциях времени выполнения, это, безусловно, верно для Java и других языков на основе JVM. Хотя я и не знаком с CLR, я думаю, что тот же принцип применяется здесь.

Хотя этот вопрос о том, что «bool» является псевдонимом типа для «System.Boolean», по существу охватывает общие случаи использования, при приближении к реализации во время выполнения диалект C # становится больше похожим на «специфичный для реализации C #», который может слегка изменить правила ,

Кристина Брукс
источник
Я проголосовал за это для вашего понимания - но я не могу пометить это как принятый ответ, потому что он не является авторитетным, извините :(
Дай