W specyfikacji kompilatora określa the behaviour of lock like so:
Typ czasu kompilacji wyrażenia instrukcji lock jest typem referencyjnym lub parametrem>> type (§25.1.1), znanym jako typ referencyjny. Jest to błąd kompilacji dla typu kompilacji czasu określający typ wartości.
Następnie określa, co jest równoznaczne z tak długo, jak to kompiluje
Rejestracja Monitor.Exit to po prostu wywołanie metody bez żadnych ograniczeń, które nie uniemożliwi kompilatorowi automatycznie boksowania int i kontynuowania jego wesołego (i bardzo) niewłaściwego sposobu.
lock
NIE jest po prostu cukrem syntaktycznym w taki sam sposób, jak foreach
nie jest po prostu cukrem syntaktycznym. Powstała transformacja IL jest , a nie przedstawiona pozostałym fragmentom kodu, tak jakby to było napisane.
Nieprawidłowe jest modyfikowanie zmiennej iteracji (mimo, że nie ma nic na poziomie IL w wynikowym kodzie, który mógłby temu zapobiec). W blokadzie kompilator zapobiega kompilacji znanych typów wartości, ponownie pomimo wynikłego IL nie dbającego o to.
Tak na marginesie:
Teoretycznie kompilator może być „błogosławiony” z intymnej znajomości tego (i innych) metod tak, że dostrzeżone oczywiste przypadki takiej sytuacji, ale zasadniczo jest to niemożliwe zawsze dostrzec to co czas kompilacji (należy rozważyć przekazanie obiektu z innej metody, złożenia lub odbicia), więc niepotrzebne jest wykrycie takich przypadków, które prawdopodobnie byłyby nieproduktywne.
Im więcej kompilator wie o wewnętrznych cechach API, tym więcej problemów będzie można uzyskać, jeśli w przyszłości będzie trzeba zmienić interfejs API.
Możliwe jest na przykład dodanie przeciążenia metody Monitor.Enter(), która zajęła wartość int i zablokowała cały proces związany z wartością int.
Byłoby to zgodne ze specyfikacją monitora (nawet jeśli byłoby to prawdopodobnie ohydne), ale powodowałoby ogromne problemy dla starszego kompilatora, który nadal radośnie uniemożliwiał operację, która stała się legalna.
Nie sądzę, że istnieje jakakolwiek kontrola. Czy blokada nie została rozwinięta za pomocą Monito.Enter w bloku try i Monitor.Exit w bloku finally. – Sandbox
nie jest rozszerzony do tego, ale najpierw kompilator spostrzega, jeśli jesteś głupi w drodze ... – ShuggyCoUk