Rozumiem, że wyliczenia są zestawiane jako stałe, więc ich zmiana powoduje przełomową zmianę. Zastanawiam się, dlaczego nie zostały one skompilowane w taki sam sposób, jak zamiast tego są statyczne zmienne readonly?Dlaczego wartości Enums zostały skompilowane jako stałe zamiast wartości statycznych?
Odpowiedz
Mogą być bardziej wydajne niż pola, więc nie ma potrzeby kompilowania ich w taki sam sposób, kiedy mogą być bezpośrednio osadzone w IL.
[Emisje] są ładowane w ten sam sposób, w jaki są ładowane wartości const. Są one osadzone bezpośrednio w IL. Z drugiej strony, Fields wymagają instrukcji obciążenia w terenie o nazwie (ldsfld), która w pewnym stopniu wpłynie na wydajność. W ten sposób wyliczenia są tak samo szybkie jak w typowym przypadku; pola są nieco wolniejsze.
(Source)
Ok, więc to była decyzja oparta na wynikach. Właśnie tego szukałem ... odpowiedzi na pytanie "dlaczego?". –
Podobnie jak w przypadku stałej, wszystkie odniesienia do poszczególnych wartości wyliczenia są przekształcane literałach liczbowych w czasie kompilacji
Więc czegoś mi brakuje?
Tak. Pytanie brzmiało: "Dlaczego są one kompilowane jako stałe zamiast statycznych readonly?" ... Zasadniczo, jaka była decyzja projektowa, aby stały się stałymi literałami zamiast statycznych readonly? –
@my, jeśli się nie mylę, to tylko do odczytu można ustawić na tworzenie i nie jest to to samo, co stałe, których nie można ustawić na instancję –
Obie podane odpowiedzi są poprawne technicznie, ale brakuje im wyjaśnienia stałych różniących się statystyką (tylko do odczytu). W języku C#, Stałe są zawsze szybsze niż tylko do odczytu, a powód jest bardzo prosty, a najlepiej wyrażone z małym przykład kodu:
const int MyConstant = 10;
static readonly int MyReadonly = 20;
static void Main()
{
int result = MyConstant + MyReadonly;
// the above statement will be resolved to:
// int result = 10 + MyReadonly
}
W czasie kompilacji, kompilator zastępuje wszystkie odniesienia do stałej z rzeczywistej wartości tej stałej . Jest to możliwe, ponieważ stała musi być wstępnie zdefiniowana podczas kompilacji. Różni się to od statycznych wartości tylko do odczytu, które choć statyczne, są faktycznie rozwiązywane w czasie wykonywania. Weźmy następujący przykład:
static readonly Encoding = Encoding.GetEncoding("GB2132");
Nie ma sposobu, aby kompilator wiedzieć, czy rzeczywiście istnieje GB2132 na maszynie, na której kod ten jest przeznaczony do uruchomienia. Jedynym sposobem na rozwiązanie tej wartości jest uruchomienie. Statyczny zapewnia, że sama wartość nie jest związana z czasem istnienia instancji i tylko w trybie odczytu zapewnia, że wartość można ustawić tylko raz. Kompilator nie może zastąpić odniesień do tego pola w czasie kompilacji, ponieważ wartość nie może być znana.
Logicznie, tylko prymitywne typy mogą być oznaczone jako stałe.
Teraz w przypadku wyliczenia jest to bardzo proste. Wyliczenia są niczym więcej niż wartością całkowitą z etykietą. Więc następujący kod:
enum MyEnum
{
First,
Second,
Third
}
static void Main()
{
MyEnum test = MyEnum.First;
if (test == MyEnum.Second)
{
// whatever
}
}
będą rozstrzygane przez kompilator do:
const int MyEnum_First = 0;
const int MyEnum_Second = 1;
const int MyEnum_Third = 2;
static void Main()
{
int test = MyEnum_First;
if (test == MyEnum_Second)
{
// whatever
}
}
co z kolei oznacza rzeczywiste odniesienia do stałych pól może zostać zastąpiona wartością znaną w czasie kompilacji, czyniąc końcowa wersja kodu coś w stylu:
static void Main()
{
int test = 0;
if (test == 1)
{
// whatever
}
}
Niesamowite wytłumaczenie, koleś – ivowiblo
Tak, ale pytanie nie było dlaczego Enums łamią zmiany, ale dlaczego Microsoft zdecydował się skompilować je jako stałe zamiast statycznych pól tylko do odczytu. Mogli kazać kompilatorowi pójść w obie strony, ale pytanie brzmiało: dlaczego używali stałych, gdy byłaby to przełomowa zmiana, a ktoś odpowiedział na to ... po prostu dla wydajności. –
- 1. Kaskadowe przykłady nie zostały skompilowane?
- 2. Jak definiować wartości stałe - najlepsza praktyka
- 3. Jak wyświetlić wartości domyślne jako puste zamiast domyślnej wartości?
- 4. Dlaczego klasa BuildConfig używa wartości Boolean.parseBoolean() zamiast wartości literalnych?
- 5. Stałe wartości w rdzeniach generycznych
- 6. Dlaczego mapa <ciąg, ciąg> akceptuje wartości jako wartości?
- 7. Czy zostały skompilowane komendy i eval Pythona?
- 8. Wywołać wstawić stare wartości - wartości, które zostały zaktualizowane
- 9. Konwersja teksty stałe do tablicy wartości (wprowadzenie wszystkie wartości w tablicy JSON)
- 10. Lista wartości: Stałe kodowe lub baza danych?
- 11. Wartości wyliczenia Scala nie zostały zamówione?
- 12. C# enums jako parametry funkcji?
- 13. dlaczego stałe Java są zadeklarowane jako statyczne?
- 14. ASP.NET MVC otrzymuje "null" jako ciąg znaków zamiast wartości zerowej
- 15. Dlaczego moje powiązanie danych pokazuje rzeczywistą wartość zamiast wartości wymuszonej?
- 16. Pobierz nazwę wyboru zamiast wartości
- 17. Perl wyjątki zamiast zwracać wartości
- 18. Go: edytuj zamiast wartości mapy
- 19. Dlaczego wewnętrzna implementacja HashSet tworzy fałszywe obiekty do wstawiania jako wartości w HashMap zamiast wstawiania wartości null?
- 20. Wyświetlanie zakresu wartości Yaxis w Matplotlib przy użyciu wartości bezwzględnych zamiast wartości przesunięcia?
- 21. Określanie wartości atrybutów jako CDATA
- 22. Zdefiniowane stałe jako argument formatu printf, dlaczego dodano "+ 0"?
- 23. Dlaczego glm :: vec reprezentuje wartości vec jako związki?
- 24. Dlaczego Python rozmowę __str__ zamiast zwracania wartości długiej
- 25. Doctrine 2: Użyj wartości 0 zamiast wartości zerowej dla relacji
- 26. dlaczego std :: make_pair pobiera dane wejściowe według wartości zamiast odniesienia do wartości stałej?
- 27. Czy Dapper obsługuje Enums?
- 28. Serialize wartości NaN do JSON jako wartości null w JSON.NET
- 29. Java: Ogólna metoda dla Enums
- 30. Brakujący błąd dla niezdefiniowanej wartości jako wartości skrótu
Wartości wyliczeń nie mogą zmieniać się w czasie wykonywania w taki sam sposób, jak przechyłki const.Gdyby były statyczne, co oznaczałoby, że ich wartość mogłaby się zmienić. –