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 booltyp 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 Booleanwydaje się, że sama struktura opiera się na specyficznych dla implementacji regułach boksu w celu implementacji rzeczywistej semantyki, takiej jak:
// 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);
}
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 boolwartość 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.Objectponieważ (z powodu skasowania typu lub w przypadku braku możliwości optymalizacji), skończyłoby się to czymś podobnym do tego, trueco odpowiada tej wartości 1.
ldc.i4.1
box [mscorlib]System.Boolean
Tak więc, gdy są na wysokim poziomie booli System.Booleanwydają się być identyczne i mogą być podobnie zoptymalizowane, w tym konkretnym przypadku w środowisku wykonawczym, różnice między wersjami pudełkową i nieopakowaną boolsą bezpośrednio widoczne. Podobnie, boolnie można porównywać rozpakowanego z System.Objectktó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 .
booljest 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.