Подтвердить что ты не робот

Использование "значения" в качестве идентификатора в С#

При написании коротких вспомогательных функций я часто обнаруживаю, что хочу использовать переменное значение "значение" в качестве аргумента. Кажется, что Visual Studio компилирует это просто отлично и не имеет никаких жалоб, когда я это делаю:

public void MyMethod(int value, bool option, string message)
{
    value = 1;
    // More code...
}

Однако Visual Studio жалуется на следующее (как и ожидалось):

private int _myProperty;
public int MyProperty
{
    get
    {
        return _myProperty;
    }
    set
    {
        int value = 0;
        _myProperty = value;
    }
}

Это заставляет меня думать, что "значение" рассматривается как ключевое слово (или нет) в зависимости от контекста. Я новичок в С#, и, насколько я знаю, я не видел ключевых слов контекста на других языках.

Вопрос: Всегда ли безопасно использовать "значение" в качестве имени переменной за пределами средства настройки свойств? Если нет, когда это можно сделать безопасно? И часто ли это считается плохой практикой?

Я был удивлен, что я не смог найти этот вопрос, который уже задал вопрос SO, и я подозреваю, что кто-то спросил его раньше. Однако его трудно найти, потому что в заголовке столько сообщений имеют "переменный" и "идентификатор". Мне не удалось найти информацию об этом в MSDN.

EDIT: Последний вопрос заключается в том, чтобы спросить, не существует ли часто или обычно. Он был изменен, чтобы отразить это.

4b9b3361

Ответ 1

Здесь MSDN говорит:

Аксессуар набора похож на метод, тип возврата которого недействителен. Он использует неявный параметр, называемый значением, тип которого является типом свойства.

Свойства - это в основном синтаксический сахар, который позволяет вам писать много методов get_Bar и set_Bar (обратите внимание: есть и другие преимущества, CLR знает это свойство). Например, если у вас есть такой класс:

public class Foo
{
    private int _bar;
    public int Bar
    {
        get { return _bar; }
        set { _bar = value; }
    }
}

Он будет генерировать IL (для сеттера), который выглядит примерно так:

.method public hidebysig specialname 
            instance void  set_Bar(int32 'value') cil managed
    {
      // 
      .maxstack  8
      IL_0000:  nop
      IL_0001:  ldarg.0
      IL_0002:  ldarg.1
      IL_0003:  stfld      int32 Program/Foo::_bar
      IL_0008:  ret
    } // end of method Foo::set_Bar

Следует отметить, что метод set_Bar принимает параметр с именем value. Таким образом, он не только похож на метод, тип возврата которого недействителен с параметром value, он на самом деле таков.

Поэтому вы не можете использовать value для чего-то еще в сеттере, очевидно.

Теперь вы должны использовать его в другом месте? Это зависит. Если это очевидно, что он имеет в виду в контексте, где вы его используете, тогда обязательно. Если value неоднозначно в определенном контексте, используйте более явное выражение.

Из MSDN:

Значение контекстного ключевого слова используется в атрибуте set в обычных объявлениях свойств.

В нем не упоминается о каком-либо другом контексте, где value считается ключевым словом, поэтому в стороне от сеттера или где-либо еще, где он может быть определен уже, вы должны быть в порядке, используя value. Это плохая практика? Как правило, не более чем любое другое потенциально двусмысленное имя переменной.

Изменить: одно место, где я думаю, что value, как имя, было бы действительно проблематичным, было бы как поле (или хуже свойство) в классе. Например:

public class Foo
{
    private int value;
    public int Value
    { 
        get { return value; }
        set { value = value; }    // which `value` are you setting? and to what?
    }
 }

Теперь вы можете удалить двусмысленность здесь с помощью this.value = value, но он все же уродлив, и мне кажется лучше использовать другое имя для вашего поля.

Ответ 2

В устройстве настройки свойств зарезервировано имя переменной value. Он используется как имя переменной, которая может быть назначена для поля поддержки.

Вопрос: Всегда ли безопасно использовать "значение" в качестве имени переменной за пределами средства настройки свойств? Если нет, когда это можно сделать безопасно? И это считается плохой практикой?

Он зарезервирован только в настройщике свойств. Это очень общее имя, но часто это может быть наилучшее описание переменной, с которой вы работаете.

Информация о MSDN

Ответ 3

Хорошо использовать value как идентификатор, находящийся вне аксессуаров set. Спецификация языка С# (ссылка на старую версию) говорит:

Поскольку у аксессуара набора неявно есть параметр с именем value, это ошибка времени компиляции для локальной переменной или константы объявление в аксессуре набора, чтобы иметь это имя.

Слово value не является (и никогда не было) полным ключевым словом в С#, даже если оно имело это специальное использование в сеттерах с С# 1.

Подробнее см. value (ссылка на С#).

Конечно, если у вас есть поле (переменная класса), называемое value, и вы хотите получить к нему доступ из аксессора set, используйте поля this.value (или NameOfYourType.value для static)).


Список реальных ключевых слов и контекстных "ключевых слов" также см. Ключевые слова С#.

Ответ 4

С# имеет множество контекстных ключевых слов. Основная причина для них в новых версиях языка заключается в том, чтобы не нарушать изменения с существующим компиляционным кодом. Контекстные ключевые слова позволяют им добавлять новую семантику, не нарушая ранее действующий код.

Как упоминалось в статье Эрика, вы всегда можете использовать @ в качестве префикса, чтобы иметь возможность использовать ключевое слово в качестве идентификатора. Я думаю, что основным преимуществом этого является способность взаимодействовать с другими библиотеками, которые могли быть разработаны на другом языке CLR с другим набором ключевых слов, где ключевое слово С# (зарезервированное или контекстное) может не быть ключевым словом на этом другом языке.

Ответ 5

Как другие ответили, значение зарезервировано для свойств, однако значение не зарезервировано специально для методов, поэтому вы можете использовать значение для переменных везде, кроме свойств setter

Однако, если вы установите значение в get, оно будет работать нормально.

Хорошо

public int MyProperty { get { int value = 0; return value; }}

Нехорошо

public int MyProperty { get { ... } set { int value = 0; _MyProperty = value }}

Ответ 6

С# имеет два типа ключевых слов: глобальные ключевые слова и контекстные ключевые слова.

Глобальные ключевые слова никогда не могут использоваться в качестве идентификаторов. Контекстные ключевые слова зарезервированы только при определенных обстоятельствах. Например, вы можете использовать большинство ключевых слов LINQ как имена переменных или методов, когда компилятор видит, что код не является запросом.

Значение зарезервировано только в установщиках свойств в качестве имени параметра. В любом другом месте вы можете использовать его как идентификатор, и это часто имеет смысл. Я думаю, что вряд ли этот контекст ключевого слова будет расширяться, потому что многие программы используют его как имя параметра, и никто не любит нарушать изменения.