В .NET тип значения (C # struct
) не может иметь конструктора без параметров. Согласно этому посту, это предусмотрено спецификацией CLI. Что происходит, так это то, что для каждого типа значения создается конструктор по умолчанию (компилятором?), Который инициализирует все члены нулем (или null
).
Почему запрещено определять такой конструктор по умолчанию?
Одно тривиальное использование для рациональных чисел:
public struct Rational {
private long numerator;
private long denominator;
public Rational(long num, long denom)
{ /* Todo: Find GCD etc. */ }
public Rational(long num)
{
numerator = num;
denominator = 1;
}
public Rational() // This is not allowed
{
numerator = 0;
denominator = 1;
}
}
Используя текущую версию C #, Rational по умолчанию - 0/0
это не так круто.
PS : параметры по умолчанию помогут решить эту проблему для C # 4.0 или будет вызван определяемый CLR конструктор по умолчанию?
Джон Скит ответил:
Чтобы использовать ваш пример, что бы вы хотели, чтобы произошло, когда кто-то сделал:
Rational[] fractions = new Rational[1000];
Должен ли он проходить через ваш конструктор 1000 раз?
Конечно, именно поэтому я и написал конструктор по умолчанию. CLR должен использовать конструктор обнуления по умолчанию, если явно не определен конструктор по умолчанию; Таким образом, вы платите только за то, что используете. Тогда, если мне нужен контейнер из 1000 нестандартных Rational
s (и я хочу оптимизировать 1000 конструкций), я буду использовать List<Rational>
вместо массива.
Эта причина, на мой взгляд, недостаточно сильна, чтобы предотвратить определение конструктора по умолчанию.
Rational()
вызывает ctor без параметров, а не Rational(long num=0, long denom=1)
.
new Rational()
будет вызывать конструктор, если он существует, однако, если он не существует, new Rational()
будет эквивалентно default(Rational)
. В любом случае вам рекомендуется использовать синтаксис, default(Rational)
когда вам нужно «нулевое значение» вашей структуры (что является «плохим» числом в предложенном вами дизайне Rational
). Значение по умолчанию для типа значения T
всегда default(T)
. Так new Rational[1000]
что никогда не будет вызывать конструкторы структуры.
denominator - 1
внутри структуры, так что значение по умолчанию становится 0/1
Then if I want a container of 1000 non-default Rationals (and want to optimize away the 1000 constructions) I will use a List<Rational> rather than an array.
Почему вы ожидаете, что массив вызовет другой конструктор для List для структуры?