Mengapa saya dapat membuat kelas bernama "var"?

103

Bukankah varkata kunci di C #? Tetapi mengapa saya bisa melakukan ini:

public class var { }

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

Yang vardigunakan dalam kode adalah varkelas yang dideklarasikan sebelum mainkelas tersebut. Dan kompilator bahkan tidak mengeluh.

Sedangkan saat saya melakukan ini:

public class int { }

atau ini:

public class true { }

Kompilator mengatakan itu intatau trueadalah kata kunci dan tidak dapat digunakan seperti itu. Kenapa tidak sama dengan var?

John Isaiah Carmona
sumber
6
Mengapa Anda ingin? Sangat membingungkan dan sulit dibaca.
duffymo
31
pertanyaan yang sangat bagus!
Richard
50
Anda juga bisa melakukannya var var = "var";dengan metode. Bagaimanapun, ini hari Jumat.
Henk Holterman
11
Saya menduga mereka membuatnya dengan cara ini agar kompatibel dengan pembuatan kode sebelum "var" berarti sesuatu yang istimewa.
vidstige

Jawaban:

101

varbukan kata kunci menurut daftar ini .

ini adalah kata kunci kontekstual, jadi dari konteksnya kompilator dapat memutuskan mana kelas Anda dan mana yang merupakan kata kunci kontekstual, dan tidak ada kebingungan yang muncul.

kata kunci kontekstualnya adalah:

digunakan untuk memberikan arti tertentu dalam kode, tetapi ini bukan kata yang dipesan di C #.

agar tidak dicadangkan, Anda dapat menggunakannya.

Seperti yang ditunjukkan pada komentar di atas terdapat pembahasan tentang perbedaan serta daftar berbagai kata kunci dan kata kunci kontekstual yang ditambahkan pada setiap versi c # di blog Eric Lipperts

Menarik untuk dicatat bahwa sejak kumpulan kata kunci diputuskan di C # 1.0 tidak ada tambahan, untuk menjaga kompatibilitas ke belakang.

Sam Holder
sumber
1
Namun itu dikategorikan di bawah "C # Kata kunci" di sini msdn.microsoft.com/en-us/library/bb383973.aspx ... membingungkan!
Richard
4
Tapi itu a Contextual Keyword. "Kata kunci kontekstual digunakan untuk memberikan arti tertentu dalam kode, tetapi ini bukan kata yang dipesan di C # . Beberapa kata kunci kontekstual, seperti parsial dan di mana, memiliki arti khusus dalam dua atau lebih konteks."
Tim Schmelter
5
@TimSchmelter Kemudian "var" adalah "kata kunci". Bukan hanya "kata khusus", kan?
luiscubal
2
Saya menduga itu untuk menjaga kompatibilitas dengan kode lama - jika seseorang memiliki kelas bernama varmaka tidak semuanya rusak saat meningkatkan C #.
Callum Rogers
1
@CallumRogers: itulah mengapa tim C # melakukan ini. Sama untuk yang lain kemudian memperkenalkan "kata kunci" seperti dari, bergabung dll (semua kontekstual dengan cara).
Abel
18

Kompiler cukup pintar untuk mengetahui bahwa konteks yang Anda gunakan varsebagai nama kelas tidak pernah menjadi konteks untuk kata kunci sehingga memungkinkannya (itulah sebabnya ia didefinisikan sebagai kata kunci kontekstual ).

Oded
sumber
Saya pikir jawaban ini setidaknya agak menyesatkan. Kompilator tidak benar-benar "cukup pintar" untuk menentukan apakah varakan digunakan sebagai kata kunci dalam kode seperti var testVar = new var();. Ya, konteksnya, dalam hal apakah tipe kustom bernama vartelah ditentukan, berperan di dalamnya, tetapi justru karena kompiler tidak cukup pintar dalam kasus tersebut untuk mengetahui apakah var testVarmerujuk ke kelas varatau ke kata kunci varyang defaultnya ke kelas dalam konteks seperti itu. Jika varkata kunci dinamai berbeda, kata kunci dapat digunakan dalam "konteks" yang sama.
ATAU Mapper
Bandingkan dengan kata kunci kontekstual lainnya, seperti add- di sini, kompilator memang tahu di setiap kejadian apakah kata kunci itu dimaksudkan (deklarasi acara; pengenal tidak akan masuk akal di sana), atau apakah kode tersebut merujuk ke pengenal (tipe atau nama dalam deklarasi, penggunaan pengenal dalam tubuh metode; kata kunci tidak akan masuk akal di sana).
ATAU Mapper
12

Cara lain untuk melihat ini: "var" sebagai kata kunci tidak ada di versi pertama C # (tidak seperti "int" dan "true"), jadi Anda mungkin telah menulis beberapa kode yang saat itu memiliki kelas yang disebut "var". Ini baik-baik saja dan legal. Kemudian ketika "var" ditambahkan ke bahasa, para desainer dengan baik hati membuatnya menjadi kata kunci hanya dalam konteks tertentu, sehingga kelas var Anda yang ada akan tetap berfungsi.

Ini adalah salah satu tantangan nyata dalam desain bahasa - cara menambahkan fitur baru tanpa merusak kode yang ada, dan tanpa membuat fitur baru menjadi rumit untuk digunakan.

Polyfun
sumber
8

Dalam versi C # sebelum versi 3, variabel lokal yang diketik secara implisit belum didukung, jadi vartidak memiliki arti khusus dan dimungkinkan untuk mendefinisikan variabel dan kelas yang dinamai var. Program contoh Anda legal, karena kedua kejadian vardi mainmerujuk ke kelas var.

C # 3 dan versi yang lebih baru kompatibel ke bawah, jadi kode yang ditulis dalam C # sebelum versi 3 masih dikompilasi dengan kompiler baru.

intdan truemerupakan kata kunci sejak C # 1.

dtb
sumber
3

Kata kunci dapat dipesan secara kontekstual. Ketika kode sumber diurai, konteks tersebut ditetapkan sebagai bagian dari pohon parse. Evaluasi kata kunci terjadi dalam konteks itu. Jadi, dalam kasus ini, var tidak berada dalam konteks yang dicadangkan dan tidak akan memiliki arti yang sama seperti saat Anda menggunakannya dalam pernyataan tugas. Saya percaya salah satu alasan untuk fleksibilitas ini adalah karena var diperkenalkan di C # 3, jadi membuatnya dicadangkan di mana-mana mungkin telah merusak kompatibilitas mundur di beberapa program, sedangkan menggunakannya sebagai deklarasi tipe variabel tidak akan dikompilasi di versi sebelumnya, jadi tidak ada kerusakan.

pfries
sumber