Можем ли мы действительно называть конструкторы без параметров конструкторами по умолчанию?

Я очень смущен значением «конструктора по умолчанию» в С#. Многие люди, включая моего профессора программирования, просто называют любой конструктор без параметров «конструктором по умолчанию» (например, в вопросах и ответах здесь или здесь) . Даже вики тега SO на default-constructor говорит, что это "конструктор без параметров... часто (обратите внимание, что он говорит часто, не всегда) генерируется компилятором".

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

Однако MSDN, если я Я правильно читаю, кажется, что имя "конструктор по умолчанию" дается только конструктору без параметров, который неявно генерируется, когда не указан другой конструктор, вызывает конструктор базового класса без параметров и (как и любой другой конструктор ) инициализирует поля class их значениями.

Если подумать, это имеет больше смысла, чем "default" == "parameterless": неявно сгенерированный конструктор похож на параметр по умолчанию, если вы не выбрали ничего другого.

Итак, правильно ли называть все конструкторы без параметров конструкторами по умолчанию?

Или правильно вызывать явно определенные конструкторы формы public C(): base() {} (для обычных классов) и protected C(): base() {} (для абстрактных классов) конструкторами по умолчанию, поскольку они соответствуют описанию конструктора по умолчанию в MSDN?

Или термин действительно применим только к неявно сгенерированным конструкторам?

Также (вероятно, самый важный вопрос): какое определение термина является наиболее распространенным, правильным или неправильным?


person Mints97    schedule 19.02.2015    source источник
comment
По-тэ-то, По-та-то. Ты совсем не выглядишь растерянным. Вы понимаете значения по умолчанию и без параметров в контексте неявно сгенерированных конструкторов без параметров. Нет необходимости исследовать эту тему дальше, кроме как обсуждать семантику, контексты, в которых излагаются вещи, и точки зрения. Двигайтесь дальше.   -  person Didaxis    schedule 19.02.2015
comment
Если вы хотите собрать такую ​​злоупотребляющую терминологию, вы также можете взглянуть на условный оператор (это а тернарный оператор, и единственный на данный момент, но это не его название); передача по ссылке против передачи по значению; необязательные параметры и именованные аргументы (и вообще аргументы/параметры, если честно).   -  person Jon Skeet    schedule 19.02.2015


Ответы (1)


Не только MSDN использует термин «конструктор по умолчанию» специально для конструктора, который предоставляется либо «если вы не укажете ничего другого», либо «всегда для структуры (до C# 6)» или «всегда для структуры». , если вы не укажете свой собственный конструктор без параметров (C# 6)" - это сама спецификация языка C#. Обратите внимание, что в случае структуры компилятору не нужно генерировать ее для вас в IL — она уже присутствует как часть системы типов.

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

List<int> x = new List<int>();
x.Add(10);
int y = x.First();

... как вызов конструктора по умолчанию для List<T>, а затем добавление к нему и т. д. - тогда нет смысла придираться к тому, что мы на самом деле вызываем конструктор без параметров. (Мы даже не можем сказать, является ли это конструктором по умолчанию, не глядя на исходный код — концепция имеет смысл только в реализации, а не извне, так сказать.)

Есть еще одно тонкое различие, о котором даже спецификация ошибается (о котором я должен сообщить об ошибке). Рассмотрим этот оператор в спецификации C# 5:

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

Это не обязательно так. Этот код компилируется нормально, несмотря на то, что Base не имеет конструктора без параметров:

public class Base
{
    public Base(int x = 0)
    {
        Console.WriteLine("Base: x={0}", x);
    }
}

public class Derived : Base
{
}

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

Следующий:

Также (вероятно, самый важный вопрос): какое определение термина является наиболее распространенным, правильным или неправильным?

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

person Jon Skeet    schedule 19.02.2015