Dlaczego mogę utworzyć klasę o nazwie „var”?

103

Czy varsłowo kluczowe nie jest w języku C #? Ale dlaczego mogę to zrobić:

public class var { }

public class main
{
    public static void main(string[] args)
    {
        var testVar = new var();
    }
}

To, varco jest używane w kodzie, to varklasa zadeklarowana przed mainklasą. A kompilator nawet nie narzeka.

Kiedy to robię:

public class int { }

albo to:

public class true { }

Kompilator powiedział, że intlub truejest słowem kluczowym i nie może być używany w ten sposób. Dlaczego to nie to samo z var?

John Isaiah Carmona
źródło
6
Dlaczego miałbyś chcieć? Tak zagmatwane i trudne do odczytania.
duffymo
31
var'y dobre pytanie!
Richard
50
Możesz także zrobić var var = "var";w metodzie. W końcu jest piątek.
Henk Holterman
11
Domyślam się, że zrobili to w ten sposób, aby być wstecznie kompatybilnym z tworzeniem kodu, zanim „zmienna” oznaczała coś specjalnego.
vidstige

Odpowiedzi:

101

varnie jest słowem kluczowym na tej liście .

jest to kontekstowe słowo kluczowe, więc na podstawie kontekstu kompilator jest w stanie zdecydować, która klasa jest twoją, a która jest kontekstowym słowem kluczowym, i nie powstaje żadne zamieszanie.

kontekstowe słowo kluczowe to:

służy do zapewnienia określonego znaczenia w kodzie, ale nie jest słowem zastrzeżonym w C #.

więc nie jest zarezerwowany, możesz go używać.

Jak wskazano w komentarzach powyżej, znajduje się omówienie różnic, a także lista różnych słów kluczowych i kontekstowych słów kluczowych dodanych w każdej wersji języka c # na blogu Erica Lippertsa

Warto zauważyć, że od kiedy ustalono zestaw słów kluczowych w C # 1.0, nie było żadnych dodatków, aby zachować zgodność wsteczną.

Sam Holder
źródło
1
Jednak jest on podzielony na kategorie w „C # Keywords” tutaj msdn.microsoft.com/en-us/library/bb383973.aspx ... mylące!
Richard
4
Ale to jest Contextual Keyword. „Kontekstowe słowo kluczowe jest używane w celu nadania określonego znaczenia w kodzie, ale nie jest to słowo zastrzeżone w języku C # . Niektóre kontekstowe słowa kluczowe, takie jak częściowe i gdzie, mają specjalne znaczenie w dwóch lub więcej kontekstach”.
Tim Schmelter
5
@TimSchmelter Zatem „var” jest „słowem kluczowym”. Po prostu nie jest to „zastrzeżone słowo”, prawda?
luiscubal
2
Domyślam się, że chodzi o zachowanie zgodności ze starym kodem - jeśli ktoś miał klasę o nazwie, varto nie wszystko psuje się podczas uaktualniania C #.
Callum Rogers
1
@CallumRogers: właśnie dlatego zespół C # to zrobił. To samo dotyczy innych później wprowadzonych „słów kluczowych”, takich jak from, join itp. (Nawiasem mówiąc, wszystkie kontekstowe).
Abel
18

Kompilator jest wystarczająco inteligentny, aby wiedzieć, że kontekst, którego używasz varjako nazwy klasy, nigdy nie jest kontekstem dla słowa kluczowego, więc pozwala na to (dlatego jest definiowany jako kontekstowe słowo kluczowe ).

Oded
źródło
Myślę, że ta odpowiedź jest co najmniej nieco myląca. Kompilator nie jest wystarczająco inteligentny, aby określić, czy varjest używany jako słowo kluczowe w kodzie takim jak var testVar = new var();. Tak, kontekst, pod względem tego, czy varzdefiniowano niestandardowy typ , gra w nim, ale to właśnie dlatego, że kompilator nie jest wystarczająco inteligentny w tych przypadkach, aby wiedzieć, czy var testVarodnosi się do klasy, varczy do słowa kluczowego, varktóre domyślnie odnosi się do klasy w takim kontekście. Gdyby varsłowo kluczowe zostało nazwane inaczej, mogłoby być używane w tym samym „kontekście”.
LUB Mapper
Porównaj to z innymi kontekstowymi słowami kluczowymi, takimi jak add- tutaj kompilator rzeczywiście wie w każdym przypadku, czy chodzi o słowo kluczowe (deklaracja zdarzenia; identyfikator nie miałby tam żadnego sensu), czy też kod odwołuje się do identyfikatora (typu lub nazwa w deklaracji, użycie identyfikatora w treści metody; słowo kluczowe nie miałoby tam żadnego sensu).
LUB Mapper
12

Patrząc na to inaczej: „var” jako słowo kluczowe nie występowało w pierwszych wersjach C # (w przeciwieństwie do „int” i „true”), więc być może napisałeś wtedy jakiś kod, który miał klasę o nazwie „var”. To było w porządku i legalne. Później, kiedy "var" zostało dodane do języka, projektanci byli tak uprzejmi, że uczyniły go słowem kluczowym tylko w określonych kontekstach, więc twoja istniejąca klasa var nadal działała.

Jest to jedno z prawdziwych wyzwań projektowania języka - jak dodawać nowe funkcje bez łamania istniejącego kodu i nie utrudniając korzystania z nowych funkcji.

Polyfun
źródło
8

W wersjach C # przed wersją 3 niejawnie wpisane zmienne lokalne nie były jeszcze obsługiwane, więc varnie miały specjalnego znaczenia i można było zdefiniować zmienne i klasy o nazwach var. Twój przykładowy program jest legalny, ponieważ obydwa występujące varw mainktórym mowa klasy var.

C # 3 i nowsze wersje są kompatybilne w dół, więc kod napisany w języku C # przed wersją 3 nadal kompiluje się z nowymi kompilatorami.

inti truesą słowami kluczowymi od C # 1.

dtb
źródło
3

Słowa kluczowe można zarezerwować kontekstowo. Kiedy kod źródłowy jest analizowany, kontekst ten jest ustanawiany jako część drzewa analizy. Ocena słów kluczowych odbywa się w tym kontekście. Tak więc w tym przypadku zmienna nie znajduje się w zarezerwowanym kontekście i nie będzie miała takiego samego znaczenia, jak wtedy, gdy używasz jej w instrukcji przypisania. Uważam, że jednym z powodów tej elastyczności jest to, że var został wprowadzony w C # 3, więc zarezerwowanie go wszędzie mogłoby zepsuć wsteczną kompatybilność w niektórych programach, podczas gdy użycie go jako deklaracji typu zmiennej nie byłoby kompilowane we wcześniejszych wersjach, więc nie ma złamanie.

pfries
źródło