Чому я можу створити клас під назвою "var"?


103

Це не varключове слово в C #? Але чому я можу це зробити:

public class var { }

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

Те, varщо використовується в коді, - це varклас, який оголошується перед mainкласом. І компілятор навіть не скаржиться.

Коли я це роблю:

public class int { }

або це:

public class true { }

Компілятор сказав, що це intабо trueє ключовим словом, і його не можна використовувати так. Чому це не те саме var?


6
Чому б ви хотіли? Так заплутано і важко читати.
— duffymo


31
варне запитання!
— Річард

50
Ви також можете зробити var var = "var";методом. Зрештою, це п’ятниця.
— Хенк Холтерман

11
Я здогадуюсь, що вони зробили це таким чином, щоб бути зворотним сумісним із створенням коду, перш ніж "var" означав щось особливе.
— vidstige

Відповіді:


101

varне є ключовим словом у цьому списку .

це контекстне ключове слово, тож із контексту компілятор може вирішити, який ваш клас, а який контекстне ключове слово, і ніякої плутанини не виникає.

контекстуальне ключове слово:

використовується для надання конкретного значення в коді, але це не зарезервоване слово в C #.

так як його не зарезервовано, ви можете використовувати його.

Як зазначалося в коментарях вище, тут обговорюються відмінності, а також перелік різних ключових слів і контекстуальних ключових слів, що додаються в кожній версії c # на блозі Еріка Ліппертса

Цікаво зауважити, що оскільки набір ключових слів вирішено в C # 1.0, не було доповнень, щоб зберегти зворотну сумісність.


1
Однак він класифікований під "C # Ключовими словами" тут msdn.microsoft.com/en-us/library/bb383973.aspx ... заплутано!
— Річард

4
Але це Contextual Keyword. "Контекстуальне ключове слово використовується для надання конкретного значення коду, але воно не є зарезервованим словом у C # . Деякі контекстуальні ключові слова, такі як часткові та де, мають особливі значення у двох чи більше контекстах."
— Тім Шмелтер

5
@TimSchmelter Тоді "var" - це "ключове слово". Тільки не "зарезервоване слово", правда?
— luiscubal

2
Я здогадуюсь, що це підтримувати сумісність зі старим кодом - якщо хтось мав клас, який названий, varто не все порушується при модернізації C #
— Каллум Роджерс

1
@CallumRogers: саме тому команда C # зробила це. Те саме для інших пізніше введених "ключових слів", таких як, приєднатися тощо (все це контекстно, до речі).
— Абель

18

Компілятор досить розумний, щоб знати, що контекст, який ви використовуєте varяк ім'я класу, ніколи не є контекстом для ключового слова, тому це дозволяє (саме тому він визначається як контекстне ключове слово ).


Я думаю, що ця відповідь принаймні дещо вводить в оману. Компілятор не є досить "розумним", щоб визначити, чи varвикористовується ключове слово в коді, як var testVar = new var();. Так, контекст, з точки зору того, чи визначений призначений для користувача тип імені var, грає в нього, але саме тому, що компілятор недостатньо розумний у цих випадках, щоб знати, чи var testVarвідноситься до класу varчи до ключового слова, varяке за замовчуванням класу в такому контексті. Якщо varключове слово було названо по-різному, воно могло використовуватися в тому самому "контексті".
— АБО Mapper

На відміну від інших контекстних ключових слів, таких як add- ось, компілятор справді знає, чи має на увазі ключове слово (декларація події; ідентифікатор там не має жодного сенсу), чи код посилається на ідентифікатор (тип або ім'я в декларації, використання ідентифікатора в тілі методу; ключове слово там не має сенсу).
— АБО Mapper

12

Іншого способу дивитися на це: "var" як ключового слова не було в перших версіях C # (на відміну від "int" та "true"), тому ви могли б написати якийсь код, у якого тоді був клас під назвою "var". Це було прекрасно і законно. Потім пізніше, коли "var" було додано до мови, дизайнери були настільки люб'язними, що перетворили його на ключове слово лише в певних контекстах, тому ваш існуючий клас var все ще працюватиме.

Це одна з реальних проблем мовного дизайну - як додавати нові функції, не порушуючи існуючий код і не роблячи нові функції громіздкими.


8

У версіях C # до версії 3 неявно введені локальні змінні ще не підтримувалися, тому varне мали особливого значення, і можна було визначити названі змінні та класи var. Ваша прикладна програма легальна, тому що обидва входження varу mainзгаданому класі var.

Версії C # 3 та новіші версії сумісні вниз, тому код, написаний на C # до версії 3, все ще компілюється з новими компіляторами.

intі trueє ключовими словами, починаючи з C # 1.


3

Ключові слова можуть бути зарезервовані контекстно. Коли вихідний код розбирається, цей контекст встановлюється як частина дерева розбору. Оцінка ключових слів відбувається в цьому контексті. Отже, у цьому випадку var не знаходиться в зарезервованому контексті і не матиме того самого значення, як коли ви використовуєте його в операторі призначення. Я вважаю, що одна з причин такої гнучкості полягає в тому, що var був введений в C # 3, тому його зарезервування скрізь може порушити сумісність у деяких програмах, тоді як використання його як декларації змінного типу не складеться в попередніх версіях, тому немає поломка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.