Kod System.Boolean
źródłowy w witrynie Source Source podaje, że instancje struct Boolean
zawierają tylko jedno bool
pole 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;
}
Ale zauważyłem, że ...
bool
to alias języka C # dlaSystem.Boolean
.- Typ jest typem
struct Boolean
wartości, co oznacza, że nie może się zawierać jako pole . - ... ale ten kod prawdopodobnie się kompiluje.
- Rozumiem, że po ustawieniu
-nostdlib
opcji kompilatora musisz podać własne podstawowe definicje typuSystem.String
, takie jakSystem.Int32
,System.Exception
- to jedyna różnica. - Opublikowany kod źródłowy nie zawiera innych specjalnych atrybutów, takich jak
[MethodImpl( MethodImplOptions.InternalCall )]
.
Jak się kompiluje ten kod?
bool
jest słowem kluczowym w języku C #. Zarówno kompilator, jak i środowisko wykonawcze mają dużo wbudowanej wiedzy o typie i nie potrzebują pomocy z System.Boolean. Deklaracje w mscorlib dla pierwotnych typów wartości są zgodne z ramkową reprezentacją typu.Odpowiedzi:
Krótka odpowiedź : jest to szczególny przypadek związany z boksowaniem typów i ich podstawową reprezentacją. Te typy są dobrze znane kompilatorowi i jako takie są traktowane nieco inaczej przez podstawowe części środowiska wykonawczego i optymalizator kompilatora / JIT w porównaniu z typowymi typami.
Ponieważ jest to zakopane głęboko w implementacji środowiska wykonawczego, przypuszczam, że specyfikacja języka nie wchodziłaby w szczegółowe szczegóły implementacji środowiska wykonawczego. Nie jestem pewien, czy jest to wystarczająca odpowiedź, ale myślę, że w tym konkretnym przypadku
bool
typ pozostaje rozpakowany, a zatem istnieje jako typ wartości surowej jako część struktury.Semantyka boksowania i rozpakowywania typów wartości jest celowo nieprzejrzysta, aby ułatwić korzystanie z języka. W tym przypadku
Boolean
wydaje się, że sama struktura opiera się na specyficznych dla implementacji regułach boksu w celu implementacji rzeczywistej semantyki, takiej jak:Wierzę w powyższe, że struktura pudełkowa reprezentująca typ boolowski jest najpierw sprawdzana pod względem typu, następnie jest rozpakowywana, a wewnętrzna
bool
wartość jest bezpośrednio porównywana. W odróżnieniu od typu pudełkowego, który może być oznakowanym wskaźnikiem lub rzeczywistą strukturą z pewnymi informacjami o typie środowiska wykonawczego, typy nieskrócone są traktowane jako dane rzeczywiste.Sądzę, że wewnętrznie, gdyby bool musiał zostać spakowany do skrzynki,
System.Object
ponieważ (z powodu skasowania typu lub w przypadku braku możliwości optymalizacji), skończyłoby się to czymś podobnym do tego,true
co odpowiada tej wartości1
.Tak więc, gdy są na wysokim poziomie
bool
iSystem.Boolean
wydają się być identyczne i mogą być podobnie zoptymalizowane, w tym konkretnym przypadku w środowisku wykonawczym, różnice między wersjami pudełkową i nieopakowanąbool
są bezpośrednio widoczne. Podobnie,bool
nie można porównywać rozpakowanego zSystem.Object
którym jest z natury typem pudełkowym. Ta odpowiedź dotycząca potrzeby boksowania / rozpakowywania idzie głębiej w wyjaśnianie samej zasady.W językach zarządzanych implementacje środowiska wykonawczego muszą być generalnie zwolnione z pewnych reguł, jeśli chodzi o niektóre podstawowe funkcje środowiska wykonawczego, z pewnością dotyczy to Javy i innych języków opartych na JVM. Chociaż nie znam również CLR, sądzę, że ta sama zasada obowiązuje tutaj.
Podczas gdy to pytanie o „bool” jest aliasem typu dla „System.Boolean” zasadniczo obejmuje ogólne przypadki użycia, podczas zbliżania się do implementacji środowiska wykonawczego dialekt języka C # przypomina bardziej „implementację specyficzną dla języka C #”, co może nieco zginać reguły .
źródło