: синтаксис this (foo) в конструкторах C#?

Время от времени я натыкаюсь на синтаксис, который видел раньше, но никогда не использовал. Это один из тех моментов.

Может ли кто-нибудь объяснить цель ": this" или ": base" после метода конструктора C#?

Например:

public MyClass(SomeArg arg) : this(new SomethingElse(), arg)
{
}

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
0
3 776
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

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

Ты прав.

: база(...) вызывает конструктор базового класса.

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

Каждый конструктор в классе .NET гарантирует, что конструктор в классе, от которого он наследуется, также вызывается.

Итак, если у вас есть следующие классы:

public class Base { }
public class Something : Base { }
public class Else : Something { }

тогда конструктор в Else вызовет конструктор в Something, который также вызовет конструктор в Base.

Конструктор, вызываемый в базовом классе (то есть в том, от которого вы производите спуск), всегда является конструктором без параметров.

Если у вас его нет или вы хотите переопределить его, вы можете переопределить его, указав базу (некоторые параметры здесь). Это выберет правильный конструктор в базовом классе.

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

Надеюсь, это было понятно.

Твое чутье в порядке. Синтаксис используется для вызова перегруженных конструкторов в том же классе:

public class Test
{
    public Test() : this("Called from default constructor") { }
    public Test(String msg)
    {
        Console.WriteLine(msg);
    }
}

Следующий код:

public static void Main(String[] args)
{
    Test t1 = new Test();
    Test t2 = new Test("Called from Main function");
}

Выводит следующие

Called from default constructor
Called from main function

Точно так же : base(someParams) используется для вызова конструкторов баз.

Точно. Назовите это Constructor Chaining, и он используется, чтобы обойти тот факт, что C# не имеет возможности использовать аргументы по умолчанию.

Это часто используется в IoC.

Это так, если не ошибаюсь:

public MyClass(SomeArg arg) : this(new SomethingElse(), arg)

позвоню

public MyClass(SomethingElse arg, SomeArg arg1) : base or this or nothing

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

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

Если у вас ничего нет, конструктор базового класса без параметров вызывается автоматически.

После того, как вы использовали this(....), будет использован конструктор, соответствующий параметрам, и будет выполнено его тело - дополнительно к телу конструктора, использовавшего this(....).

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

Another use of the this keyword is to force one constructor to call another in order to avoid redundant member initialization logic.

в Pro C# 2005 и платформе .NET 2.0, 3-е издание Эндрю Трольсен

Другие вопросы по теме