Когда вы используете ключевое слово «это»? [закрыто]

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

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

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

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

public void SomeMethod()
{
    Vector vec = new Vector();
    double d = (vec * vec) - (this.radius * this.radius);
}
22.08.2008 19:21:25
Я нашел хорошие примеры, когда вам действительно нужно this на MSDN. Пожалуйста, перейдите по этой ссылке ... ;-)
Matt 18.02.2014 08:38:57
Если вам нужно понять и оптимизировать или переписать кого-то другого, в основном плохо написанный код, который вы были бы рады иметь, thisили любой другой классификатор, чтобы из простого взгляда вы знали область действия переменной (особенно пропущенные квалификаторы класса для констант (тот же пакет или иерархия) или super/ baseклассификаторы). И использование обычно используемого синтаксиса вроде _fooне кажется мне элегантным. Нажатие _на intellisense занимает больше времени, чем ввод this. И зачем вообще? С функцией автоматического сохранения eclipse нет необходимости, _если вы забыли классификатор.
djmj 29.05.2014 15:20:28
После прочтения ответов и комментариев ниже, а также прочтения документации MSDN: docs.microsoft.com/en-us/previous-versions/visualstudio/… об этом ключевом слове, которое не обновлялось в течение 6 лет, я бы предложил никогда не использовать это ключевое слово. Это бессмысленно. Не делайте параметры одинаковыми, это сбивает с толку и глупо. Почему ты бы так поступил? Кроме того, не передавайте экземпляр в использовании этого , это также сбивает с толку и глупо.
Yusha 10.07.2019 18:35:12
30 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

218
23.05.2017 11:47:19
8. Чтобы вызвать метод расширения для текущего экземпляра ( this.Foo();будет работать, но Foo()не будет)
Marc Gravell♦ 17.11.2011 13:20:49
Также для приведения себя к другому типу, например, явно реализованный метод будет вызываться как ((ICollection<T>)this).Add(bla).
nawfal 13.11.2013 18:02:33
Чтобы связать конструкцию с другим конструктором, определенным в том же типе. public ClassName(...) : this(...),
Lasse V. Karlsen 4.07.2014 20:34:01
@ И это никак не повлияет на производительность во время выполнения. Предполагая, что двусмысленности нет, выходные данные компилятора одинаковы, независимо от того, пишете ли вы, например, this.someField = someValueили someField = someValue. Это может повлиять на производительность компилятора, так как компилятор будет анализировать исходный код по-разному, но любая разница наверняка будет незначительной.
phoog 5.05.2015 20:58:26
Вы можете избежать первой проблемы, получая доступ к полям через свойства, только если вы придерживаетесь стилевого соглашения, согласно которому свойства не могут иметь те же имена, что и параметры. Просто так получается, что распространенное соглашение о стиле C # отвечает этому требованию. Однако не все C # написаны в соответствии с этим соглашением. В свойствах как таковых нет ничего, что сделало бы thisключевое слово ненужным; вызываемый параметр конструктора xбудет скрывать вызываемый член, xнезависимо от того, является ли он полем, свойством или событием.
phoog 5.05.2015 21:04:42

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

38
22.08.2008 19:22:48
Я хочу как можно больше различать переменные класса, чтобы код был более понятным. Я использовал префикс m_ (переменная-член), например, личная строка m_name. Теперь я просто использую это, например, если у меня есть класс Test {private string a; public someMethod () {this.a = "foo"; }}
broadband 10.01.2014 11:17:10

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

5
22.08.2008 19:23:02

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

1
22.08.2008 19:23:16

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

3
22.08.2008 19:23:34

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

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

}

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

96
16.05.2018 06:29:40
В этом случае, почему бы просто не дать разные имена входным переменным конструктора?
wz366 14.05.2018 23:20:11

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

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

Пример:

void onChange()
{
    screen.draw(this);
}
11
22.08.2008 19:26:37

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

1
22.08.2008 19:29:51

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

0
22.08.2008 19:30:42

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

7
22.08.2008 19:31:26

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

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

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

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

36
23.05.2017 12:02:53
@ JasonBunting : Вы не можете иногда делать что-то, а не что-то другое ... это сбивает с толку ... Я надеюсь, что я никогда не буду работать с вашим кодом. Вы не всегда можете предположить, что человек, который читает ваш код в будущем, поймет, что вы писал, что вам нужно , чтобы быть как можно более четкими, и один из способов достижения этого является быть последовательным
juan 22.08.2008 19:51:13
@juan, 10 лет спустя. Вы все еще думаете, что «это» - хорошая практика? :)
Scott Adams 19.06.2019 03:19:33
@ScottAdams я до сих пор верю в последовательности и ясности, да
juan 19.06.2019 13:10:53
Как насчет определения области видимости переменной (локальной или членской), просто взглянув на нее? Разве «это» не оправдано для этой цели? Или вы хотите сказать, что если мы напишем меньшие методы, было бы достаточно легко понять область действия переменной в любом случае?
BornToCode 26.06.2019 09:45:28

Никогда. Когда-либо. Если у вас есть переменное затенение, ваши соглашения об именах находятся в полном порядке. Я имею в виду, действительно, никаких отличительных имен для переменных-членов? Facepalm

-8
22.08.2008 19:53:31
+1. Я не полностью согласен (аргументы метода?), Но это очень верный момент.
Askolein 21.01.2014 12:53:22

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

27
22.08.2008 20:00:47
И ReSharper говорит мне не использовать его. Что-то вроде путаницы, когда я использую и StyleCop, и ReSharper одновременно :) Но я склоняюсь к ответу Coreys, приведенному выше, использовать ключевое слово «this» только в случае крайней необходимости.
Gunnar 24.05.2013 11:55:17
@Gunnar, есть возможность отключить избавление от лишнего «это». в R #
Winger Sendon 26.02.2016 20:56:34
@EmperorAiman ​​- Да, я знаю. Я хотел сказать, что эти два популярных инструмента форматирования по умолчанию предлагают две разные вещи, и это может сбивать с толку. «Быть ​​или не быть ...» :)
Gunnar 26.04.2016 11:17:30

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

Шутки в сторону.

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

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

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

246
16.03.2011 09:27:03
thisКлючевое слово семантически значимым. Смотрите комментарий @ JasonBunting ниже. Вы путаете стилистическое злоупотребление thisс его фактическим назначением. Ваше замечание не просто легкомысленно, это неправильно!
Dan Barowy 4.06.2013 16:43:00
Если у вас есть шанс, вы можете перечитать мой ответ. Я говорю об использовании его в тех случаях, когда это необходимо для правильной семантики. Вы также можете посмотреть на вопрос о происхождении. Это показывает использование в примерах, где это не семантически необходимо. Итак, я не уверен, что именно то, что я сказал, было «неправильно». Мой ответ, конечно, не легкомысленный.
Scott Wisniewski 5.06.2013 02:12:58
Ты знаешь, как мой ответ звучит для меня? Между строк я читаю "Как ты смеешь задавать такой вопрос?" - Это действительно не конструктивно, на мой взгляд. Никто не знает всего - вот почему у нас есть Stackoverflow: помогать другим и получать помощь. Некоторые темы вы знаете, некоторые знают другие. Помогайте друг другу, не сражайтесь друг с другом. Пожалуйста, подумайте об этом.
Matt 5.02.2014 10:00:56
Я не хочу показаться странным, но это пока один из худших ответов. Я не понимаю, насколько полезно сравнивать это с вашей работой или личной жизнью. Тот факт, что некоторые вещи менее важны, чем другие, не означает, что они не важны . Наличие последовательного стиля программирования не является неважным (прочитайте книгу о читаемости / удобстве сопровождения кода по вашему выбору).
aioobe 15.03.2015 07:51:51
Я думаю, что вы, возможно, неправильно поняли мою точку зрения. Это не значит, что «иметь последовательный стиль» - это плохо. Я ничего не говорю об этом. Это вопрос о том, «должен ли мой стиль руководить мандатом« это ». в качестве префикса для всех полевых доступов? " произвольно и капризно.
Scott Wisniewski 15.03.2015 19:20:21

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

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

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

4
22.08.2008 21:19:47

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

54
23.08.2008 05:05:44
но если вы забудете использовать его когда-нибудь, они
surfen 4.12.2011 00:21:42
@surfen, которого можно избежать с помощью дополнительных проверок стилей, например, в Java вы можете использовать Checkstyle и запускать его после полной сборки (и на любом популярном итеративном / OO-языке будут аналогичные инструменты)
Maarten Bodewes 8.01.2014 12:01:16
@ Surfen, как будто вы забыли это в неоднозначных случаях. Я могу нарушить любой аргумент, сказав «но если вы забудете ...».
Askolein 21.01.2014 12:49:42
Кажется, что большинство людей никогда не читают, не оптимизируют и не переписывают чужой код! Квалификаторы экономят время и мотивацию! Без классификатора это похоже на магию, если вы видите произвольную строку кода. Таким образом, вы тратите все время, просто проверяя, откуда эти переменные.
djmj 29.05.2014 15:26:01
Я знаю, что это очень старый пост, но не могу не прокомментировать иронию этого ответа (с которым я случайно согласен). В «Джихаде против злой венгерской нотации» любой, кто осмелился префиксировать свои переменные-члены с «m_», был быстро поставлен на позор, потому что различать переменные-члены было просто бесполезно или не нужно.
Michael J. 4.11.2016 14:25:58

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

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

2
26.08.2008 02:00:07

[C ++]

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

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

  • Передача «себя» в функцию.
  • Назначение «себя» указателю или что-то в этом роде.
  • Литье, то есть литье вверх / вниз (безопасное или иное), постоянство отливки и т. Д.
  • Компилятор принудительно устраняет неоднозначность.
4
26.08.2008 17:25:29

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

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

-2
2.09.2008 16:42:19

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

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 
1
6.09.2008 11:50:15

[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
16.09.2008 07:25:18

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

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

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

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

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

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

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

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

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

1
19.09.2008 19:47:04

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

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

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}
5
19.09.2008 19:58:13

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

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

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

3
7.10.2014 08:11:58

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

0
23.05.2017 12:34:36

1 - идиома общего Java-сеттера:

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

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

notifier.addListener(this);
0
20.09.2008 03:47:38

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

Нажатие CTRL + Пробел не помогает в этом, потому что он также включает типы; где-как "это" включает членов ТОЛЬКО.

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

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

1
16.03.2009 11:38:04

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

1
23.04.2009 18:54:08

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

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

1
23.04.2009 20:12:37

Есть одно использование, которое еще не было упомянуто в 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
2.02.2010 08:22:36