Лучшая практика для C # автоматически реализуемого свойства и локальной переменной, которые различаются только регистром?

Позвольте мне привести Вам пример:

public class MyClass
{
    public string MyProperty { get; set; }

    public MyClass(string myProperty)
    {
        MyProperty = myProperty; // bad?
        this.MyProperty = myProperty; // good?
    }
}

Я стал использовать this в этом сценарии, потому что у меня есть небольшая паранойя: полагаться только на случай может сбить с толку или, что еще хуже, привести к ошибкам.

Какая здесь «лучшая практика»?

РЕДАКТИРОВАТЬ:

Пока что это звучит гораздо более субъективно, чем я думал. Я полагал, что люди будут сильно недооценивать ту или иную сторону.


person devuxer    schedule 30.09.2009    source источник
comment
StyleCop настоятельно рекомендует использовать this.   -  person Sam Harwell    schedule 30.09.2009
comment
@ 280Z28, StyleCop всегда поощряет использование this или только в тех случаях, когда есть локальная переменная, которая отличается только регистром?   -  person devuxer    schedule 30.09.2009
comment
Я был в магазинах, которые делают и то, и другое - удалите это или потребуйте добавить его. В любом случае я не очень сильно к этому отношусь :)   -  person womp    schedule 30.09.2009
comment
Это пахнет плохим дизайном. Почему вы хотите реализовать свойство в подклассе с тем же именем, что и свойство во внешнем классе? Какой вариант использования?   -  person cllpse    schedule 01.10.2009
comment
@roosteronacid, здесь только одно свойство. Другой - аргумент конструктора.   -  person Pavel Minaev    schedule 01.10.2009
comment
Да. Извини за это. Становится поздно :)   -  person cllpse    schedule 01.10.2009


Ответы (7)


Использование "this." излишне в любом классе. Задача разработчика - установить стандарт его использования.

Плюсы использования «this.» заключаются в том, что некоторым разработчикам легче связать его в уме с экземпляром класса, когда они читают код, и, как вы упомянули, сделать его более понятным при работе с элементами с одинаковыми именами.

Минусы в том, что некоторые люди считают, что это загромождает ваш файл кода, и если вы используете такие инструменты, как ReSharper, они по умолчанию помечают его как избыточный код.

person womp    schedule 30.09.2009
comment
Кстати, у Resharper есть опции, чтобы заставить это, особенно если вы используете что-то вроде StyleCop для Resharper. - person Reed Copsey; 30.09.2009
comment
это не полностью избыточно. Если у вас есть локальная переменная с именем myThing и переменная экземпляра с именем myThing, тогда myThing ссылается на локальную переменную, а this.myThing ссылается на переменную экземпляра. - person Jim Mischel; 30.09.2009
comment
Насколько я помню, this.myVariable рекомендуется избегать использования венгерской нотации. В этом случае this.myVariable рекомендуется вместо m_myVariable. - person Steve Guidi; 30.09.2009
comment
@Steve Guidi ... но, вероятно, не предпочтительнее использовать только подчеркивание (как в _myVariable), что кажется очень распространенной практикой, хотя официально не одобрено MS. - person devuxer; 30.09.2009
comment
@Jim Mischel - хороший момент, он действительно используется в качестве квалификатора области видимости. Но это также указывает на потенциальный запах кода. - person womp; 30.09.2009
comment
@womp - запах кода. Что и было смыслом моего ответа. Насколько я понимаю, лучший способ - не делать этого. - person Jim Mischel; 30.09.2009
comment
@womp, что вы предлагаете в качестве альтернативы. Сценарий в моем вопросе - это то, что произойдет, если вы будете следовать стандартным правилам именования. Как вы предлагаете устранять неоднозначность переданных локальных переменных из свойств с одинаковыми именами? Как я говорю в комментарии ниже, использование чего-то вроде localMyProperty - это в основном венгерская нотация ... не будет ли это также запахом кода (или, по крайней мере, плохим стилем)? - person devuxer; 01.10.2009
comment
Я считаю это полезным. Я также использую base и NameOfClass (для статических переменных). - person Jodi; 01.10.2009
comment
@Dan - Я не утверждаю, что это плохо, я просто говорю, что это сильно зависит от того, что люди принимают (как вы можете видеть). Если ваши программисты всегда передают имена переменных, которые совпадают с именами свойств, и вы не можете устранить неоднозначность, вам обязательно следует принять это. Я бы не стал предлагать венгерский, который почти повсеместно презирают, за исключением нескольких случаев в настоящее время. - person womp; 01.10.2009
comment
@Womp, мне кажется, я неправильно понял, что вы сказали, это запах кода. Наличие локальной переменной и вспомогательного поля с одинаковыми именами и case, вероятно, будет считаться запахом кода. Вот почему я использую подчеркивание во всех своих полях. - person devuxer; 01.10.2009
comment
@DanThMan - да, это то, о чем я имел в виду (мой комментарий был направлен на то, что описание Джима экземпляра и локальных переменных названо одинаково). Если это вообще имеет значение, наш магазин также использует символы подчеркивания для префикса частных полей, а мы это не используем. - person womp; 01.10.2009
comment
для меня, если у вас есть имена переменных экземпляра myVariable и член с именем myVariable, это запах кода, и его следует реорганизовать. - person krystan honour; 14.04.2010

Как сказал womp. "this" является избыточным, но упрощает чтение кода. Или, скорее, труднее ошибиться.

person Sani Singh Huttunen    schedule 30.09.2009

C # определенно чувствителен к регистру, поэтому нет никакого риска в использовании ...

MyProperty = myProperty;

Тогда я бы обратился к другим передовым методам, например к написанию наименьшего количества кода, необходимого для достижения вашей цели (при самодокументировании). По правде говоря, это не обязательно, минималисты могут сказать, что это не нужно.

person DrivenDevelopment    schedule 30.09.2009

Вот как я в настоящее время инициализирую свойства, используя ваш пример (как автоматически, так и нет)

        public class MyClass
    {
        public string MyProperty { get; set; }

        public string AnotherProperty
        {
            get { return _anotherProperty; }
            set { _anotherProperty = value; }
        }
        private string _anotherProperty;

        public MyClass(string myProperty, string anotherProperty)
        {
            MyProperty = myProperty; // auto-implemented property initialization
            _anotherProperty = anotherProperty; //property with member variable initialization                
        }
    }

Мне кажется, что использование слова «это» является чрезмерным. Я знаю, что это местная собственность, потому что она капитализирована. Все свойства должны быть заглавными. Я знаю, что переменная _anotherProperty имеет область видимости класса из-за подчеркивания. Раньше я опускал подчеркивание в переменных уровня класса. Мне легче читать код, когда есть подчеркивание, потому что я сразу знаю область действия, не наводя указатель мыши на переменную, чтобы увидеть объявление во всплывающей подсказке от VS. Кроме того, я могу использовать одно и то же имя для локальных переменных, просто опуская нижнее подчеркивание. Это делает ваши инициализации чистыми. Еще одним преимуществом подчеркивания является то, что вы можете ввести подчеркивание и нажать ctrl + пробел, и все ваши переменные в области класса будут сгруппированы.

person Steve    schedule 30.09.2009
comment
Спасибо, мне нравится ваше объяснение. Я определенно использую подчеркивание для резервных полей именно по указанным вами причинам. И я никогда не использую ключевое слово this, если нет локальной переменной в той же области с тем же именем и в другом регистре. - person devuxer; 01.10.2009

На моем рабочем месте стандарты кодирования диктуют, что свойства должны быть записаны как это, а локальные переменные должны быть записаны как это. Поскольку C # чувствителен к регистру, это хороший инструмент для различения переменных. Однако, если вы обнаружите, что свойство и локальная переменная имеют одно и то же имя, использование ключевого слова this определенно устранит неоднозначность использования.

person Doctor Blue    schedule 30.09.2009

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

person Robin Day    schedule 30.09.2009
comment
Конечно, есть. У одного есть 5 дополнительных символов, которые читаются тем, кто просматривает код, что может помочь или затруднить понимание читателем. - person Brian; 30.09.2009
comment
Подождите, но разве не было бы неуспешно сказать MyProperty = this.myProperty?. Другими словами, не this. гарантирует, что то, что идет после этого, является свойством или переменной уровня класса? Если да, то как можно сказать, что разница только в регистре? - person devuxer; 30.09.2009

На мой взгляд, «лучший способ» здесь - «не делай этого». Если я натыкаюсь на это в проверяемом коде, я немедленно отмечаю это. Наличие двух переменных, которые различаются только регистром, - недоразумение, которое только и ждет своего часа. Программисту по обслуживанию слишком легко прийти спустя месяцы или годы и нечаянно назначить myThing вместо MyThing.

Добавлено позже:

Комментатор попросил меня предложить заменить соглашение об именах в верхнем / нижнем регистре. Для этого мне нужен конкретный пример. Допустим, у вас есть простой Book класс, у которого есть только одно свойство: Title:

public class Book
{
    public string Title { get; private set; }
}

Теперь вам нужен конструктор. Распространенным соглашением является использование версии свойства в нижнем регистре:

public Book(string title)
{
    Title = title;
}

Или, если вы хотите убедиться в отсутствии двусмысленности: this.Title = title.

Можно утверждать, что в конструкторах это нормально. И могло бы быть, если бы все конструкторы были такими простыми. Но мой опыт показывает, что когда конструктор выходит за рамки нескольких строк, различие между Title и title теряется. Проблема усугубляется, когда вы говорите о методах, отличных от конструкторов. В любом случае вам нужно другое соглашение.

Что использовать? Я по-разному использовал и видел используемые сокращения в параметрах: ttl, например. Или что-то вроде bookTitle, что более наглядно при использовании Intellisense. На мой взгляд, любой вариант предпочтительнее обычного использования имени, которое отличается только регистром.

person Jim Mischel    schedule 30.09.2009
comment
Есть ли у вас соглашение об именах, позволяющее избежать этой проблемы? Ненавижу называть всех своих местных жителей localMyThing. Это в основном венгерская нотация. - person devuxer; 30.09.2009
comment
Настроить StyleCop так, чтобы любые ссылки на свойства (и поля) были квалифицированы как this, тривиально, что делает слишком легким случайное присвоение неверного аргумента. - person Pavel Minaev; 01.10.2009
comment
@Pavel: конечно, настроить StyleCop для этого - нетрудно. Если вы не считаете, что принуждение к этому - необоснованное бремя. Если вы это сделаете, вы также можете принудительно указать полную спецификацию для всех ссылок. То есть больше не Thread.Sleep (10), а скорее System.Threading.Thread.Sleep (10). Также: для программиста столь же тривиально отказаться от использования StyleCop. Когда вы их используете, такие инструменты, как StyleCop, отлично подходят для соблюдения соглашений. Но их слишком легко обойти. - person Jim Mischel; 01.10.2009