Сведения о вопросе

ЧОВИД

14:20, 2nd August, 2020

Теги

c#   coding-style   this    

Когда вы используете ключевое слово "this"?

Просмотров: 446   Ответов: 25

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

В конструкторе:

public Light(Vector v)
{
    this.dir = new Vector(v);
}

В другом месте

public void SomeMethod()
{
    Vector vec = new Vector();
    double d = (vec * vec) - (this.radius * this.radius);
}



  Сведения об ответе

qwerty101

08:10, 25th August, 2020

Я не хочу, чтобы это прозвучало язвительно, но это не имеет значения.

Серьезно.

Посмотрите на вещи, которые важны: ваш проект, ваш код, ваша работа, ваша личная жизнь. Ни один из них не будет иметь своего успеха rest от того, используете ли вы ключевое слово "this" для квалификации доступа к полям. Это ключевое слово не поможет вам отправить вовремя. Это не уменьшит количество ошибок, не окажет заметного влияния на качество кода или его ремонтопригодность. Это не даст вам прибавку к зарплате или позволит проводить меньше времени в офисе.

На самом деле это просто вопрос стиля. Если вам нравится "this", то используйте его. Если вам это нужно, чтобы получить правильную семантику, то используйте его. Правда в том, что каждый программист имеет свой собственный уникальный стиль программирования. Этот стиль отражает представления конкретного программиста о том, как должен выглядеть "most aesthetically pleasing code". По определению, любой другой программист, который читает ваш код, будет иметь другой стиль программирования. Это означает, что всегда будет что-то, что вы сделали, что другой парень не любит или сделал бы по-другому. В какой-то момент какой-то парень прочитает ваш код и будет ворчать о чем-то.

Я бы не переживал из-за этого. Я просто хотел бы убедиться, что код настолько эстетичен, насколько это возможно в соответствии с вашими собственными вкусами. Если вы спросите 10 программистов, как форматировать код, вы получите около 15 различных мнений. Лучше сосредоточиться на том, как код учитывается. Правильно ли все абстрагировано? Разве я выбирал для вещей осмысленные названия? Есть ли много дублирования кода? Есть ли способы, которыми я могу все упростить? Я думаю, что правильное решение этих вопросов окажет самое большое положительное влияние на ваш проект, ваш код, вашу работу и вашу жизнь. По совпадению, это, вероятно, также заставит другого парня ворчать меньше всего. Если ваш код работает, легко читается и хорошо учитывается, другой парень не будет тщательно изучать, как вы инициализируете поля. Он просто будет использовать ваш код, восхищаться его величием, а затем перейдет к чему-то другому.


  Сведения об ответе

PHPH

15:16, 4th August, 2020

Существует несколько вариантов использования этого ключевого слова в C#.

  1. Чтобы квалифицировать участников, скрытых под похожим именем
  2. Чтобы объект передавал себя в качестве параметра другим методам
  3. Чтобы объект возвращал себя из метода
  4. Для объявления индексаторов
  5. Для объявления методов расширения
  6. Передача параметров между конструкторами
  7. Чтобы внутренне переназначить значение типа значения (struct).
  8. Чтобы вызвать метод расширения на текущем экземпляре
  9. Чтобы привести себя к другому типу
  10. Для цепных конструкторов, определенных в том же классе

Вы можете избежать первого использования, не имея членовых и локальных переменных с одинаковыми именами в области видимости, например, следуя общим соглашениям об именовании и используя свойства (Pascal case) вместо полей (camel case), чтобы избежать столкновения с локальными переменными (также camel case). В C# 3.0 поля могут быть легко преобразованы в свойства с помощью автоматически реализуемых свойств .


  Сведения об ответе

прога

23:57, 12th August, 2020

Я использую его только тогда, когда это абсолютно необходимо, т. е. когда другая переменная затеняет другую. Такие как здесь:

class Vector3
{
    float x;
    float y;
    float z;

    public Vector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

}

Или, как указывает Райан Фокс, Когда вам нужно передать это в качестве параметра. (Локальные переменные имеют приоритет над переменными-членами)


  Сведения об ответе

lourence

01:13, 9th August, 2020

Лично я стараюсь всегда использовать это при обращении к переменным-членам. Это помогает уточнить код и сделать его более читаемым. Даже если нет никакой двусмысленности, кто-то, читающий мой код в первый раз, не знает этого, но если он видит, что это используется последовательно, он будет знать, смотрит ли он на переменную-член или нет.


  Сведения об ответе

KOMP

00:19, 2nd August, 2020

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


  Сведения об ответе

VCe znayu

03:29, 12th August, 2020

Я не могу поверить, что все люди, которые говорят, что использование его всегда является "best practice" и так далее.

Используйте "this", когда есть неопределенность, как в Примере кори , или когда вам нужно передать объект в качестве параметра, как в Примере Райана . Нет никакой причины использовать его иначе, потому что возможность разрешить переменную на основе цепочки областей должна быть достаточно ясной, чтобы квалифицирующие переменные с ней не были нужны.

EDIT: документация C# по "this" указывает на еще одно использование, помимо двух упомянутых мною, ключевого слова "this" - для объявления индексаторов

EDIT: @Juan: Да, я не вижу никакой несогласованности в своих заявлениях - есть 3 случая, когда я использовал бы ключевое слово "this" (как описано в документации C#), и это время, когда вам действительно это нужно . Вставлять "this" перед переменными в конструкторе, когда нет никакого затенения, - это просто пустая трата клавиш и моего времени при чтении, это не дает никакой пользы.


  Сведения об ответе

PAGE

21:06, 1st October, 2020

Я использую его всякий раз, когда StyleCop говорит мне об этом. StyleCop должно быть исполнено. - О да.


  Сведения об ответе

прога

08:19, 17th August, 2020

В любой момент вам понадобится ссылка на текущий объект.

Один особенно удобный сценарий - это когда ваш объект вызывает функцию и хочет передать себя в нее.

Пример:

void onChange()
{
    screen.draw(this);
}


  Сведения об ответе

prince

19:02, 25th August, 2020

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


  Сведения об ответе

FAriza

22:47, 12th August, 2020

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


  Сведения об ответе

ITSME

15:35, 22nd August, 2020

Еще одно несколько редкое использование этого ключевого слова - когда вам нужно вызвать явную реализацию интерфейса из класса реализации. Вот надуманный пример:

class Example : ICloneable
{
    private void CallClone()
    {
        object clone = ((ICloneable)this).Clone();
    }

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}


  Сведения об ответе

VERSUION

12:44, 25th August, 2020

Вот когда я его использую:

  • Доступ к частным методам из класса (для дифференциации)
  • Передача текущего объекта другому методу (или в качестве объекта-отправителя, в случае события)
  • При создании методов расширения: D

Я не использую это для частных полей, потому что я префиксую имена переменных частных полей с подчеркиванием (_).


  Сведения об ответе

PAGE

15:10, 22nd August, 2020

[C++]

Я согласен с бригадой "use it when you have to". Излишне украшать код этим не очень хорошая идея, потому что компилятор не предупредит вас, когда вы забудете это сделать. Это создает потенциальную путаницу для людей, ожидающих, что это всегда будет там, т. е. им придется думать об этом.

Итак, когда бы вы его использовали? Я только что осмотрел какой-то случайный код и нашел эти примеры (я не выношу суждения о том, являются ли эти вещи хорошими или нет):

  • Передача функции "yourself".
  • Присвоение "yourself" указателю или что-то в этом роде.
  • Отливки, т. е. вверх/вниз отливок (безопасный или иначе), отбросить константность и др.
  • Компилятор ввел двусмысленность.


  Сведения об ответе

DINO

23:18, 21st August, 2020

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

Например

class AABB
{
  // ... members
  bool intersects( AABB other )
  {
    return other.left() < this->right() &&
           this->left() < other.right() &&

           // +y increases going down
           other.top() < this->bottom() &&
           this->top() < other.bottom() ;
  }
} ;

(против)

class AABB
{
  bool intersects( AABB other )
  {
    return other.left() < right() &&
           left() < other.right() &&

           // +y increases going down
           other.top() < bottom() &&
           top() < other.bottom() ;
  }
} ;

На первый взгляд, к какому AABB относится right() ? this добавляет немного осветлителя.


  Сведения об ответе

park

21:19, 8th August, 2020

В ответе Якуба Штурца его #5 о передаче данных между контрукторами, вероятно, можно было бы немного пояснить. Это происходит в перегруженных конструкторах и является единственным случаем, когда использование this является обязательным. В следующем примере мы можем вызвать параметризованный конструктор из конструктора без параметров с параметром по умолчанию.

class MyClass {
    private int _x
    public MyClass() : this(5) {}
    public MyClass(int v) { _x = v;}
}

Я обнаружил, что это особенно полезная функция в некоторых случаях.


  Сведения об ответе

darknet

08:30, 23rd August, 2020

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


  Сведения об ответе

ЯЯ__4

04:31, 23rd August, 2020

У меня вошло в привычку свободно использовать его в Visual C++, так как это вызовет IntelliSense, когда я нажму клавишу'>', и я ленив. (и склонны к опечаткам)

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


  Сведения об ответе

прога

00:20, 29th August, 2020

- вот это.'помогает найти членов в классе 'this' с большим количеством членов (обычно из-за глубокой цепочки наследования).

Нажатие CTRL+пробел не помогает в этом, потому что оно также включает типы; where-as 'this.- включая членов ONLY.

Я обычно удаляю его, как только у меня есть то, что мне было нужно: но это просто мой стиль прорыва.

С точки зрения стиля, Если вы одинокий рейнджер - вы решаете; если вы работаете на компанию, придерживайтесь политики компании (посмотрите на материал в системе управления версиями и посмотрите, что делают другие люди). С точки зрения использования его для квалификации членов, ни то, ни другое не является правильным или неправильным. Единственное неправильное - это непоследовательность , это золотое правило стиля. Оставь этих придурков подбирать другим. Вместо этого потратьте свое время на обдумывание реальных проблем кодирования-и, очевидно, кодирования-вместо этого.


  Сведения об ответе

fo_I_K

17:00, 15th August, 2020

Я обычно подчеркиваю поля с_, так что на самом деле никогда не нужно использовать это. Кроме того, R# имеет тенденцию к рефакторингу их в любом случае...


  Сведения об ответе

piter

19:15, 7th August, 2020

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


  Сведения об ответе

ЯЯ__4

00:39, 4th August, 2020

Я использую его только при необходимости, за исключением симметричных операций, которые из - за полиморфизма одного аргумента должны быть помещены в методы одной стороны:

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 


  Сведения об ответе

fo_I_K

06:04, 21st August, 2020

[C++]

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

A a;
a = a;

Ваш оператор назначения будет записан:

A& A::operator=(const A& a) {
    if (this == &a) return *this;

    // we know both sides of the = operator are different, do something...

    return *this;
}


  Сведения об ответе

repe

21:06, 1st October, 2020

this на компиляторе C++

Компилятор C++ будет автоматически искать символ, если он не найдет его немедленно. Иногда, в большинстве случаев, это хорошо:

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

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

Для меня это время, когда внутри метода я хочу получить доступ к методу-члену или переменной-члену. Я просто не хочу, чтобы какой-то случайный символ был выбран только потому, что я написал printf вместо print . this->printf не стал бы компилироваться.

Дело в том, что с C устаревшими библиотеками ( § ), устаревшим кодом, написанным много лет назад ( § § ), или тем, что может произойти в языке, где копирование/вставка является устаревшей, но все еще активной функцией, иногда, говоря компилятору, чтобы он не играл в Остроумие, это отличная идея.

Вот почему я использую this .

( § ) это все еще остается для меня загадкой, но теперь я задаюсь вопросом, является ли тот факт, что вы включаете заголовок <windows.h> в свой источник, причиной того, что все унаследованные символы библиотек C будут загрязнять ваше глобальное пространство имен

( § § ) осознание того, что "вам нужно включить заголовок, но что включение этого заголовка нарушит ваш код, потому что он использует какой-то тупой макрос с общим именем", является одним из тех моментов русской рулетки в жизни кодера


  Сведения об ответе

SKY

22:12, 1st August, 2020

Существует одно использование, которое еще не было упомянуто в C++, и это не относится к собственному объекту или не вызывает неоднозначности члена из полученной переменной.

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

template <typename T>
struct base {
   void f() {}
};

template <typename T>
struct derived : public base<T>
{
   void test() {
      //f(); // [1] error
      base<T>::f(); // quite verbose if there is more than one argument, but valid
      this->f(); // f is now an argument dependent symbol
   }
}

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

На этом этапе компилятор практически не имеет информации о том, что такое base<T> (обратите внимание, что специализация базового шаблона может превратить его в совершенно разные типы, даже неопределенные типы), поэтому он просто предполагает, что это тип. На этом этапе несамостоятельный вызов f , который кажется просто естественным для программиста, является символом, который компилятор должен найти как член derived или в замкнутых пространствах имен-чего не происходит в Примере - и он будет жаловаться.

Решение заключается в превращении несамостоятельного имени f в зависимое имя. Это можно сделать несколькими способами, явно указав тип, в котором он реализован ( base<T>::f -- добавление base<T> делает символ зависимым от T , и компилятор просто предположит, что он будет существовать, и отложит фактическую проверку для второго прохода, после замены аргумента.

Второй способ, гораздо более сортирующий, если вы наследуете от шаблонов, которые имеют более одного аргумента или длинных имен, - это просто добавление this-> перед символом. Поскольку класс шаблона, который вы реализуете, зависит от аргумента (он наследуется от base<T>), this-> зависит от аргумента, и мы получаем тот же результат: this->f проверяется во втором раунде, после замены параметров шаблона.


  Сведения об ответе

lourence

02:04, 20th August, 2020

Это зависит от стандарта кодирования, под которым я работаю. Если мы используем _ для обозначения переменной экземпляра, то "this" становится избыточным. Если мы не используем _ , то я склонен использовать это для обозначения переменной экземпляра.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться