This c что это
Перейти к содержимому

This c что это

  • автор:

This c что это

В прошлой статье для создания объекта использовался конструктор по умолчанию. Однако мы сами можем определить свои конструкторы. Как правило, конструктор выполняет инициализацию объекта. При этом если в классе определяются свои конструкторы, то он лишается конструктора по умолчанию.

На уровне кода конструктор представляет метод, который называется по имени класса, который может иметь параметры, но для него не надо определять возвращаемый тип. Например, определим в классе Person простейший конструктор:

Итак, здесь определен конструктор, который выводит на консоль некоторое сообщение и инициализирует поля класса.

Конструкторы могут иметь модификаторы, которые указываются перед именем конструктора. Так, в данном случае, чтобы конструктор был доступен вне класса Person, он определен с модификатором public .

Определив конструктор, мы можем вызвать его для создания объекта Person:

В данном случае выражение Person() как раз представляет вызов определенного в классе конструктора (это больше не автоматический конструктор по умолчанию, которого у класса теперь нет). Соответственно при его выполнении на консоли будет выводиться строка «Создание объекта Person»

Подобным образом мы можем определять и другие конструкторы в классе. Например, изменим класс Person следующим образом:

Теперь в классе определено три конструктора, каждый из которых принимает различное количество параметров и устанавливает значения полей класса. И мы можем вызвать один из этих конструкторов для создания объекта класса.

Консольный вывод данной программы:

Стоит отметить, что начиная с версии C# 9 мы можем сократить вызов конструктора, убрав из него название типа:

Ключевое слово this

Ключевое слово this представляет ссылку на текущий экземпляр/объект класса. В каких ситуациях оно нам может пригодиться?

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

первая часть — this.name означает, что name — это поле текущего класса, а не название параметра name. Если бы у нас параметры и поля назывались по-разному, то использовать слово this было бы необязательно. Также через ключевое слово this можно обращаться к любому полю или методу.

Цепочка вызова конструкторов

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

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

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

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

И если при вызове конструктора мы не передаем значение для какого-то параметра, то применяется значение по умолчанию.

Инициализаторы объектов

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

С помощью инициализатора объектов можно присваивать значения всем доступным полям и свойствам объекта в момент создания. При использовании инициализаторов следует учитывать следующие моменты:

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

Инициализатор выполняется после конструктора, поэтому если и в конструкторе, и в инициализаторе устанавливаются значения одних и тех же полей и свойств, то значения, устанавливаемые в конструкторе, заменяются значениями из инициализатора.

Инициализаторы удобно применять, когда поле или свойство класса представляет другой класс:

Обратите внимание, как устанавливается поле company :

Деконструкторы

Деконструкторы (не путать с деструкторами) позволяют выполнить декомпозицию объекта на отдельные части.

Например, пусть у нас есть следующий класс Person:

В этом случае мы могли бы выполнить декомпозицию объекта Person так:

Значения переменным из деконструктора передаюся по позиции. То есть первое возвращаемое значение в виде параметра personName передается первой переменной — name, второе возващаемое значение — переменной age.

По сути деконструкторы это не более,чем более удобный способ разложения объекта на компоненты. Это все равно, что если бы мы написали:

При получении значений из деконструктора нам необходимо предоставить столько переменных, сколько деконструктор возвращает значений. Однако бывает, что не все эти значения нужны. И вместо возвращаемых значений мы можм использовать прочерк _ . Например, нам надо получить только возраст пользователя:

Поскольку первое возвращаемое значение — это имя пользователя, которое не нужно, в в данном случае вместо переменной прочерк.

Ключевое слово this . Назначение. Особенности применения в классах

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

2. Случаи применения ключевого слова this в программах на C#

Ключевое слово this применяется в следующих случаях.

  1. Когда в методе класса существует имя, совпадающее с именем поля класса.
  2. Если в классе есть несколько конструкторов, то this применяется для вызова главного конструктора из других (перенаправление на главный конструктор). Это осуществляется с целью избежания дублирования кода.
  3. Когда в метод нужно передать ссылку на текущий объект. В этом случае, при вызове метода, указывается ключевое слово this .
  4. Если в классе объявлен индексатор.
3. Пример использования this для доступа к полям класса из тела метода

В примере, в классе Program объявляются два метода и два конструктора:

  • конструктор Program() без параметров;
  • конструктор Program() с одним параметром. В этом конструкторе продемонстрировано использование this для инициализации поля класса;
  • метод PrintInt() – демонстрирует доступ к полю класса, имя которого перекрывается именем параметра метода;
  • метод Print() – демонстрирует доступ к полю класса, имя которого перекрывается именем внутренней переменной, объявленной в методе.

Текст программы следующий

Результат работы программы

4. Пример применения this для вызова конструкторов класса

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

Задан класс Line , определяющий линию заданную координатами двух крайних точек (x1; y1), (x2; y2). В классе продемонстрирован вызов конструкторов с помощью ключевого слова this .

В нашем случае главный конструктор – это конструктор с 4 параметрами.

Текст программы демонстрации класса Line следующий:

Результат работы программы

5. Передача методу ссылки на текущий объект. Пример

Если в метод класса нужно передать текущий экземпляр этого класса, то используется ключевое слово this . В приведенном ниже примере ключевое слово this применяется в методе DisplayLengthOrigin() класса Point при вызове метода LengthOrigin() этого же класса.

Демонстрационный текст приложения типа Console Application следующий:

Результат работы программы:

6. Пример использования ключевого слова this для объявления индексатора

В примере реализован класс ArrayIntegers , который реализует массив целых чисел. Для доступа к элементу массива используется механизм индексаторов. В индексаторе используется ключевое слово this , которое символизирует обращение к текущему экземпляру класса. Более подробно об особенностях использования индексаторов в классах можно прочитать здесь.

Демонстрационный текст программы, созданной по шаблону Console Application приведен ниже.

Результат работы программы

7. В каких случаях в классе нельзя применять ключевое слово this ?

Ключевое слово this нельзя применять:

  • в статических методах класса;
  • в статических классах.

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

The this pointer

The expression this is a prvalue expression whose value is the address of the implicit object parameter (object on which the non-static member function (until C++23) implicit object member function (since C++23) is being called). It can appear in the following contexts:

  • dynamic exception specification,
  • noexcept specification, and
  • the trailing return type.

[edit] Explanation

this can only associate with the innermost enclosing class of its appearance, even if the appearance is invalid in the context:

The type of this in a member function of class X is X* (pointer to X). If the member function is declared with a cv-qualifier sequence cv, the type of this is cv X* (pointer to identically cv-qualified X). Since constructors and destructors cannot be declared with cv-qualifiers, the type of this in them is always X* , even when constructing or destroying a const object.

When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit this-> is automatically added before the name, resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).

In class templates, this is a dependent expression, and explicit this-> may be used to force another expression to become dependent.

During construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor’s this pointer, the value of the object or subobject thus obtained is unspecified. In other words, the this pointer cannot be aliased in a constructor:

It is possible to execute delete this ; , if the program can guarantee that the object was allocated by new , however, this renders every pointer to the deallocated object invalid, including the this pointer itself: after delete this ; returns, such member function cannot refer to a member of a class (since this involves an implicit dereference of this ) and no other member function may be called.

This can be used in the member function of the reference-counting pointer (for example, std::shared_ptr ) (since C++11) responsible for decrementing the reference count, when the last reference to the managed object goes out of scope.

[edit] Keywords

[edit] Example

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

What is the purpose of 'this' keyword in C#

Since variables declared inside a method are available only within that method, and variables declared private within a class are only available within a class. What is the purpose of the this key word? Why would I want to have the following:

When this will do the exact same thing:

to practice my typing skills?

19 Answers 19

There are a couple of cases where it matters:

If you have a function parameter and a member variable with the same names, you need to be able to distinguish them:

If you actually need to reference the current object, rather than one of its members. Perhaps you need to pass it to another function:

Of course the same applies if you want to return a reference to the current object

In your example it is purely a matter of taste, but here is a case where it is not:

Without this , the code would work differently, assigning the parameter to itself.

R. Martinho Fernandes's user avatar

There are many cases where this is useful. Here’s one example:

Here’s another example. Suppose I were writing a Stream.Out method that outputs an object, and returns a reference to the stream itself, like so:

Then, one could use this Out call in a chained mode:

In addition to the «field disambiguation» and «passing a reference of the current isntance» answers (already given), there is an additional scenario where this is necessary; to call extension methods on the current instance (I’m ignoring the usage of this in declaring an extension method, as that isn’t quite the same meaning as the question):

To be fair, this isn’t a common scenario. A more likely one is simply to make code more readable, for example:

In the above (or similarly for Compare , Clone etc), without the this. I find it a little. «unbalanced».

Marc Gravell's user avatar

In most cases, using this simply clutters the code. However, I’ve seen it used by other programmers, presumably to trigger the intellisense for members of the local class.

The this keyword is also required for use in extension methods.

Firstly, your examples are flawed because you’ve marked the class as static, so it cannot be instantiated.

Regardless, this is simply a reference to the current instance. It can be used to resolve conflicts between local variables and member variables, for example:

It can also be used simply as an object in its own right, for example:

(Not that this example is particularly useful, but you get the idea.)

Edit: A more realistic example is the event model in .NET:

You need this if your method-parameter has the same name as the field.

The first thing that comes into my mind is readability and/or personal preference.

Sometimes when I am working with a rather large class. or a class with a base class (where I cannot «see» some variables). I utilize the «this» keyword. at minimum for intellisense in Visual Studio.

Outside of perhaps Javascript, «this» is mostly a placeholder keyword and it is most useful is making your intent obvious when writing a piece of code.

Basically it will help with readability.

  1. this signifies your current class instance member not
    a. your base class member
    b. scope member
    c. static member
  2. To make your code more readable.

First and foremost, this is necessary when a class method needs to pass a reference to the object to some method in another class.

Unlike some other scenarios where using or not using «this.» is a matter of style, or a means for resolving an artificial ambiguity.

Seva Alekseyev's user avatar

I respectfully disagree with some of the other posters. In C#, it isn’t just a matter of taste; it is also in line with Microsoft’s C# style guidelines (both internally and externally, though they do not seem to ahdere to their own guidelines internally).

There are examples of cases when the notation you used will not work:

Instead, you would need to use the following notation:

this refers to the instance of the class, and in the example you show us: you use this to refer to the field called variablename .

If you had a local variable or parameter with the same name, you would need to have a way of differentiating between them. In that case this will refer to the field, while not prefixing with this refers to the local variable or parameter.

You should have a naming convention that helps you differ between fields and locals. This will save you from the troubles that could occur if you later added a local with the same name to your method. (Since code without this would then break. )

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *