Як "System.Boolean" mscorlib уникає циклів компонування структури?


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- псевдонім мови C # для System.Boolean.
  • Тип - struct Booleanце тип типу значення, що означає, що він не може містити себе як поле .
  • ... все ж цей код, імовірно, складається.
  • Я розумію , що коли -nostdlibпараметр компілятора встановлений вам необхідно надати свої власні основні визначення типу подобається System.String, System.Int32, System.Exception- це єдина відмінність.
  • Опублікований вихідний код не містить інших спеціальних атрибутів, таких як [MethodImpl( MethodImplOptions.InternalCall )].

То як складається цей код?


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значення безпосередньо порівнюється. На відміну від типу в коробці, який може бути тегованим покажчиком або фактичною структурою з деякою інформацією про тип виконання, необоротні типи трактуються як фактичні дані.

Я вірю всередину, якби бул повинен був бути встановлений в боксі, щоб його передали як 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 # для реалізації", який може трохи зменшити правила. .


Я підтримав це для вашого розуміння, але я не можу відзначити це прийнятою відповіддю, оскільки це не є авторитетним, вибачте :(
Дай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.