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:
// 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 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ści 1
.
ldc.i4.1
box [mscorlib]System.Boolean
Tak więc, gdy są na wysokim poziomie bool
i System.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 z System.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 .
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.