Инициализатор поля не может ссылаться на нестатические поля, метод или свойство?
У меня есть класс репозитория и класс служб, как показано ниже:
public class DinnerRepository
{
DinnerDataContext db = new DinnerDataContext();
public Dinner GetDinner(int id)
{
return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
}
// Others Code
}
public class Service
{
DinnerRepository repo = new DinnerRepository();
Dinner dinner = repo.GetDinner(5);
// Other Code
}
Это вызывает ошибку:
Инициализатор поля не может ссылаться на нестатические поля, метод или свойство.
Несмотря на то, что я включил класс DinnerRepository, выставляем его метод GetDinner() в классе обслуживания. Это отлично работает с кодом ниже. Есть ли альтернатива этому, или это стандартная практика? Я не могу использовать статические методы здесь.
public class Service
{
public Service()
{
DinnerRepository repo = new DinnerRepository();
Dinner dinner = repo.GetDinner(5);
}
}
Ответы
Ответ 1
Лично я просто инициализирую поля в конструкторе:
public class Service
{
private readonly DinnerRepository repo;
private readonly Dinner dinner;
public Service()
{
repo = new DinnerRepository();
dinner = repo.GetDinner(5);
}
}
Обратите внимание, что это не то же самое, что код, который вы показываете в нижней части вопроса, поскольку это только объявление локальных переменных. Если вам нужны только локальные переменные, это хорошо, но если вам нужны переменные экземпляра, используйте код, как указано выше.
В принципе, инициализаторы полей ограничены тем, что они могут сделать. Из раздела 10.5.5.2 спецификации С# 4:
Инициализатор переменных для поля экземпляра не может ссылаться на создаваемый экземпляр. Таким образом, это ошибка времени компиляции для ссылки this
в инициализаторе переменной, поскольку это ошибка времени компиляции для инициализатора переменной для ссылки на любой экземпляр элемента через простое имя.
( "Таким образом" и "поэтому" выглядит неправильно для меня - это незаконно ссылаться на элемент через простое имя, потому что оно ссылается на this
- я буду пинговать Mads об этом, но это в основном соответствующий раздел.)
Ответ 2
Даже если выражения инициализации гарантированы в "textual order" , это незаконно для инициализаторов полей экземпляра для доступа к this
ссылке, и вы неявно используете его в
Dinner dinner = repo.GetDinner(5);
что эквивалентно
Dinner dinner = this.repo.GetDinner(5);
Лучшей практикой IMHO является резервирование инициализации поля до постоянных значений или простой инструкции new
. Что-нибудь более волосатое, чем это должно идти к конструктору.