Правильное использование этого. ключевое слово в C #?

Я работаю над книгой Head First C # (и пока все идет хорошо), но у меня много проблем с тем, чтобы понять синтаксис, связанный с использованием «this». ключевое слово.

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

Есть ли у кого-нибудь хорошие практические правила, которым они следуют, применяя «это»? Или любые онлайн-руководства, которые объясняют это иначе, чем Head First C #?

Спасибо!


person user236494    schedule 21.02.2010    source источник
comment
возможный дубликат Когда вы используете ключевое слово this?   -  person nawfal    schedule 13.11.2013


Ответы (5)


Лично я использую его только тогда, когда мне нужно:

  • Конструктор цепочки:

    public Foo(int x) : this(x, null)
    {
    }
    
    public Foo(int x, string name)
    {
        ...
    }
    
  • Копирование имени параметра в поле (не так часто в C #, как в Java, поскольку вы обычно используете свойство, но обычно в конструкторах)

    public void SetName(string name)
    {
        // Just "name = name" would be no-op; within this method,
        // "name" refers to the parameter, not the field
        this.name = name;
    }
    
  • Обращение к этому объекту без участия каких-либо членов:

    Console.WriteLine(this);
    
  • Объявление метода расширения:

    public static TimeSpan Days(this int days)
    {
        return TimeSpan.FromDays(days);
    }
    

Некоторые другие люди всегда используют его (например, для других вызовов методов) - лично я считаю, что это немного мешает.

person Jon Skeet    schedule 21.02.2010
comment
Ключевое слово также используется для методов расширения. - person masfenix; 21.02.2010
comment
@Jon, меня интересуют твои мысли по поводу твоего второго примера. Лично я бы просто назвал поле поддержки как-то иначе, чтобы избежать конфликтов, и убрать необходимость в ключевом слове this. (Обычно что-то вроде '_name' для закрытых полей участника) - person Simon P Stevens; 21.02.2010
comment
@masfenix: Спасибо, добавлю это. @Simon: Нет, мне это нравится. Мне не нравятся префиксы (я считаю, что это мешает мне читать), и если я выбрал имя для концепции, то, по-видимому, это лучшее, что я могу придумать. Боль писать это. иногда относительно небольшой. - person Jon Skeet; 21.02.2010
comment
Так что, по сути, это личное дело, а не техническая причина отдавать предпочтение одному другому. Спасибо. - person Simon P Stevens; 21.02.2010

Стиль кодирования по умолчанию StyleCop требует соблюдения следующего правила:

A1101: вызов {имя метода или свойства} должен начинаться с "this". префикс, чтобы указать, что элемент является членом класса.

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

person Mathias    schedule 21.02.2010
comment
Я думаю, что это одно из самых глупых правил StyleCop, уступающее только размещению комментария в каждом закрытом поле. - person John Saunders; 21.02.2010

Я пишу this. тогда и только тогда, когда это улучшает читаемость, например, при реализации Comparable интерфейса (Java, но идея та же):

public void compareTo(MyClass other) {
  if (this.someField > other.someField) return 1;
  if (this.someField < other.someField) return -1;
  return 0;
}

Что касается затенения параметров (например, в конструкторах): я обычно даю им более короткое имя соответствующего поля, например:

class Rect {
  private int width, height;
  public Rect(int w, int h) {
    width = w;
    height = h;
  }
}
person Thomas    schedule 21.02.2010

По сути, this дает вам ссылку на текущий объект. Вы можете использовать его для доступа к членам объекта или для передачи текущего объекта в качестве параметров другим методам.

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

Лично я стараюсь, чтобы мои переменные-члены четко отличались от моих параметров, чтобы никогда не использовать this. Например:

private String _someData;
public String SomeData
{
    get{return _someData;}
    set{_someData = value;}
}

Тем не менее, это в значительной степени индивидуальное предпочтение, и некоторые люди будут рекомендовать вам одинаково называть свойство и переменную-член (разница только в регистрах - 'someData' и 'SomeData') и использовать ключевое слово this при доступе к закрытому элементу, чтобы указать разницу. .

Итак, практическое правило - избегайте его использования. Если вы обнаружите, что используете его, чтобы различать переменные local / parameters и переменные-члены, переименуйте одну из них, чтобы вам не приходилось использовать this.

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

person Simon P Stevens    schedule 21.02.2010

Если у вас есть метод внутри класса, который использует те же поля класса, вы можете использовать это.

public class FullName
    {
        public string fn { set; get; }
        public string sn { set; get; }

        //overriding Equals method
        public override bool Equals(object obj)
        {
            if (!(obj is FullName))
                return false;

            if (obj == null)
                return false;

            return this.fn == ((FullName)obj).fn &&
            this.sn == ((FullName)obj).sn;
        }

        //overriding GetHashCode
        public override int GetHashCode()
        {
            return this.fn.GetHashCode() ^ this.sn.GetHashCode(); 
        }
    }
person Anil    schedule 09.10.2014