При использовании инициализатора объекта я попытался создать экземпляр ICollection через инициализатор массива по ошибке (я забыл часть new ...
). Что странно, так это то, что компилятор не жаловался на время компиляции, но во время выполнения я получил исключение NullReferenceException.Инициализатор массива действителен во время компиляции, но не выполняется во время выполнения, когда внутри инициализатора объекта
Вот код, чтобы подвести итог ситуации:
public class FakeClass
{
public ICollection<string> StringsCollection { get; set; }
public string[] StringsArray { get; set; }
}
FakeClass c = new FakeClass();
c.StringsCollection = { "test" }; // doesn't compile - ok
c.StringsCollection = new string[] { "test" }; // compiles - ok
c.StringsArray = { "test" }; // doesn't compile - ok
c.StringsArray = new string[] { "test" }; // compiles - ok
string[] strings = { "sdfqgrt" }; // compiles - ok
strings = { "sdfqgrt" }; // doesn't compile - ok
FakeClass c2 = new FakeClass
{
StringsCollection = { "rthtj" }, // compiles and throws at run - why?
StringsArray = { "egryjt" } // doesn't compile - ok
};
Конечно, я понимаю, почему этот код не может работать, но мне любопытно, как компилятор может принять такую вещь.
Вы используете {get; set}, который не инициализирует ICollection. Добавьте инициализацию в конструктор для класса или замените {get; set;} с вызовом конструктору: новый ICollection() –
jdweng
Инициализаторы используют приятный синтаксический сахар, слишком много сахара имеет тенденцию производить гнилые зубы. Синтаксис действителен, вы используете инициализатор * collection * (а не инициализатор поля), для этого требуется только метод Add(). Таким образом, он вызывает * getter *, а не setter для получения ссылки на сборку, это значение null. Избежать ошибок, подобных этому, не так просто, вам придется посещать школу Hard Knocks. –