C #: После копирования класса & ldquo; this & rdquo; ключевое слово выбрасывает ошибку [дубликат]

229
задан 7 revs, 6 users 47% 7 October 2014 в 09:10
поделиться

30 ответов

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

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

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

204
ответ дан 9 revs, 5 users 49% 31 August 2018 в 10:04
поделиться

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

0
ответ дан 31 August 2018 в 10:04
поделиться

Я использую его для вызова Intellisense так же, как JohnMcG , но я вернусь и удалю «this->», когда закончите. Я следую соглашению Microsoft о префиксах переменных-членов с помощью «m_», поэтому оставляя его, поскольку документация будет просто избыточной.

1
ответ дан 2 revs 31 August 2018 в 10:04
поделиться

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

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

Я обнаружил, что это особенно полезно.

3
ответ дан 2 revs, 2 users 78% 31 August 2018 в 10:04
поделиться

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

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;
    }

}

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

93
ответ дан 2 revs, 2 users 97% 31 August 2018 в 10:04
поделиться

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

Серьезно.

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

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

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

235
ответ дан 3 revs, 2 users 90% 31 August 2018 в 10:04
поделиться

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

Используйте «это», когда есть двусмысленность, как в примере Кори или когда вам нужно передать объект в качестве параметра, как в примере Райана . Нет причин использовать его иначе, потому что возможность разрешить переменную, основанную на цепочке областей видимости, должна быть достаточно ясной, чтобы необязательные переменные с ней были бы лишними.

РЕДАКТИРОВАТЬ: документация на C # на этом «указывает» еще одно использование, помимо двух, о которых я упоминал, для ключевого слова «this» - для объявления индексаторов

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

37
ответ дан 7 revs, 3 users 56% 31 August 2018 в 10:04
поделиться

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

1
ответ дан akmad 31 August 2018 в 10:04
поделиться

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

Например

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() ;
  }
} ;

(vs)

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 добавляет немного осветлителя.

3
ответ дан bobobobo 31 August 2018 в 10:04
поделиться

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

48
ответ дан Brandon Wood 31 August 2018 в 10:04
поделиться

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

0
ответ дан Dan Blair 31 August 2018 в 10:04
поделиться

Существует одно использование, которое еще не упоминалось в 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 проверяется во втором раунде после замены параметра шаблона .

0
ответ дан David Rodríguez - dribeas 31 August 2018 в 10:04
поделиться

Вы не должны использовать «это», если не будете абсолютно необходимы.

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

-1
ответ дан dicroce 31 August 2018 в 10:04
поделиться

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

27
ответ дан Ian Nelson 31 August 2018 в 10:04
поделиться

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

1
ответ дан JamesSugrue 31 August 2018 в 10:04
поделиться

Я получил привычку использовать его в Visual C ++, так как это приведет к запуску IntelliSense, я ударил ключ «>», и я ленив. (и склонны к опечаткам)

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

2
ответ дан JohnMcG 31 August 2018 в 10:04
поделиться

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

Удар CTRL + Space не помогает в этом, потому что он также включает типы; где - как «это».

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

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

1
ответ дан Jonathan C Dickinson 31 August 2018 в 10:04
поделиться

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

2
ответ дан juan 31 August 2018 в 10:04
поделиться

[C ++]

Я согласен с тем, что «используйте его, когда вам нужно» бригадировать. Без кода без кода [this] это не является отличной идеей, потому что компилятор не предупредит вас, когда вы забудете это сделать. Это вводит потенциальную путаницу для людей, ожидающих, что этот всегда будет там, т. Е. Им придется думать об этом .

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

  • Передача «себя» в функцию.
  • Назначение «себя» указателю или что-то в этом роде.
  • Литье, т.е. литье вверх / вниз (безопасное или иное), отбрасывание константы и т. д.
  • Компилятор принудительной неоднозначности.
4
ответ дан Nick 31 August 2018 в 10:04
поделиться

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

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

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

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

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

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

Вот причины, по которым я использую this.

(§) для меня какая-то тайна, но теперь я задаюсь вопросом, включает ли тот факт, что вы включили & lt; windows.h & gt; заголовок в вашем источнике, является причиной того, что все устаревшие символы библиотек C загрязнят ваше глобальное пространство имен

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

1
ответ дан paercebal 31 August 2018 в 10:04
поделиться

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

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

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}
5
ответ дан Paul Batum 31 August 2018 в 10:04
поделиться

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

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

0
ответ дан Paw Baltzersen 31 August 2018 в 10:04
поделиться

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

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 
1
ответ дан Pete Kirkham 31 August 2018 в 10:04
поделиться

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

6
ответ дан Philippe 31 August 2018 в 10:04
поделиться

Каждый раз, когда вам нужна ссылка на текущий объект.

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

Пример:

void onChange()
{
    screen.draw(this);
}
11
ответ дан Ryan Fox 31 August 2018 в 10:04
поделиться

1 - Идиот общей итерации Java:

 public void setFoo(int foo) {
     this.foo = foo;
 }

2 - При вызове функции с этим объектом в качестве параметра

notifier.addListener(this);
0
ответ дан slim 31 August 2018 в 10:04
поделиться

[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;
}
1
ответ дан Stacker 31 August 2018 в 10:04
поделиться

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

5
ответ дан TheSmurf 31 August 2018 в 10:04
поделиться

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

35
ответ дан Thomas Owens 31 August 2018 в 10:04
поделиться

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

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

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

4
ответ дан Vaibhav 31 August 2018 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: