У .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
(і хочу оптимізувати 1000 конструкцій), я буду використовувати List<Rational>
скоріше масив.
Ця причина, на мій погляд, недостатньо сильна, щоб запобігти визначенню конструктора за замовчуванням.
Rational()
викликає безпараметричний ctor, а не the 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.
Чому ви очікуєте, що масив викликає інший конструктор до списку для структури?