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

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

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

Например:

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

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

7 ответов

Решение

Ты в принципе прав. this() вызывает конструктор в текущем экземпляре, 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");
}

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

Вызывается из конструктора по умолчанию
Вызывается из основной функции

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

Ты прав.

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

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

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

Так что если у вас есть следующие классы:

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

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

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

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

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

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

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

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

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

Именно так. Назовите его 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(....),

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