'System.Boolean` ของ mscorlib จะหลีกเลี่ยงวงจรโครงร่างอย่างไร


10

ซอร์สโค้ดสำหรับSystem.Booleanที่เว็บไซต์แหล่งอ้างอิงระบุว่าอินสแตนซ์ของ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 สำหรับประเภทค่าดั้งเดิมตรงกับการแสดงชนิดบรรจุกล่อง
Hans Passant

คำตอบ:


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(เพราะลบออกประเภทหรือในกรณีที่ไม่มีการเพิ่มประสิทธิภาพจะเป็นไปได้) ที่คุณจะจบลงด้วยสิ่งที่ตามสายของนี้ซึ่งในกล่องค่า true1

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

ดังนั้นในขณะที่อยู่ในระดับสูงboolและSystem.Booleanดูเหมือนจะเหมือนกันและอาจได้รับการปรับให้เหมาะสมในทำนองเดียวกันในกรณีนี้โดยเฉพาะในรันไทม์ความแตกต่างระหว่างรุ่นที่บรรจุกล่องและที่ไม่มีกล่องboolจะถูกเปิดเผยโดยตรง ที่คล้ายกันกล่องที่boolไม่ได้ถูกเปรียบเทียบก็ไม่สามารถเทียบได้กับSystem.Objectประเภทที่บรรจุอยู่ในกล่อง คำตอบนี้เกี่ยวกับความต้องการในการชกมวย / การบอกเลิกจะลึกมากขึ้นเท่าที่อธิบายหลักการเอง

ในการใช้งานรันไทม์ภาษาที่มีการจัดการโดยทั่วไปจะต้องได้รับการยกเว้นจากกฎบางอย่างเมื่อมันมาถึงคุณสมบัติหลักของรันไทม์บางสิ่งนี้เป็นจริงสำหรับ Java และภาษาที่ใช้ JVM อื่น ๆ ในขณะที่ฉันไม่คุ้นเคยกับ CLR เช่นกันฉันจะคิดว่ามีหลักการเดียวกันนี้ที่ใช้

ในขณะที่คำถามนี้เกี่ยวกับ 'บูล' เป็นนามแฝงประเภทสำหรับ 'System.Boolean'เป็นหลักครอบคลุมกรณีการใช้งานทั่วไปเมื่อเข้าใกล้การใช้งานจริงภาษาของ C # จะกลายเป็นเหมือน "การใช้งานเฉพาะ C #" ซึ่งสามารถดัดกฎเล็กน้อย .


ฉันอัปโหลดสิ่งนี้เพื่อความเข้าใจของคุณ - แต่ฉันไม่สามารถทำเครื่องหมายว่านี่เป็นคำตอบที่ยอมรับได้เพราะมันไม่ได้มีอำนาจขอโทษ :(
ได
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.