Я столкнулся с этой проблемой сегодня при создании struct
для хранения набора данных. Вот пример:
public struct ExampleStruct
{
public int Value { get; private set; }
public ExampleStruct(int value = 1)
: this()
{
Value = value;
}
}
Выглядит хорошо и денди. Проблема заключается в том, что я пытаюсь использовать этот конструктор без указания значения и хочу использовать значение по умолчанию 1 для параметра:
private static void Main(string[] args)
{
ExampleStruct example1 = new ExampleStruct();
Console.WriteLine(example1.Value);
}
Этот код выводит 0
и не выводит 1
. Причина в том, что все структуры имеют общедоступные конструкторы без параметров. Итак, подобно тому, как я вызываю this()
свой явный конструктор, в Main
происходит то же самое, когда new ExampleStruct()
фактически вызывает ExampleStruct()
, но не вызывает ExampleStruct(int value = 1)
. Поскольку он это делает, он использует значение int
по умолчанию, равное 0, как Value
.
Что еще хуже, мой фактический код проверяет, находится ли параметр int value = 1
в допустимом диапазоне внутри конструктора. Добавьте это в конструктор ExampleStruct(int value = 1)
выше:
if(value < 1 || value > 3)
{
throw new ArgumentException("Value is out of range");
}
Итак, на данный момент конструктор по умолчанию фактически создал объект, который недействителен в том контексте, для которого он мне нужен. Кто-нибудь знает, как я могу:
- A. Вызовите конструктор
ExampleStruct(int value = 1)
. - B. Измените способ заполнения значений по умолчанию для конструктора
ExampleStruct()
. - C. Некоторые другие предложения/варианты.
Кроме того, я знаю, что мог бы использовать такое поле вместо моего свойства Value
:
public readonly int Value;
Но моя философия заключается в том, чтобы использовать поля в частном порядке, если они не const
или static
.
Наконец, причина, по которой я использую struct
вместо class
, заключается в том, что это просто объект для хранения неизменяемых данных, который должен быть полностью заполнен при его построении и при передаче в качестве параметра не должен быть в состоянии быть null
(поскольку он передается по значению как struct
), для чего и предназначены структуры.
struct
, вы все равно можете сделать все это сclass
и просто броситьArgumentNullException
. Основные причины использованияstrcut
описаны в MSDN: msdn.microsoft.com/ en-us/library/ms229017.aspx - person James Michael Hare   schedule 15.11.2012