字段初始值设定项不能引用非静态字段、方法或属性?
Posted
技术标签:
【中文标题】字段初始值设定项不能引用非静态字段、方法或属性?【英文标题】:A field initializer cannot reference the non-static field, method, or property? 【发布时间】:2011-11-16 01:44:21 【问题描述】:我有一个存储库类和一个服务类,如下所示:
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);
请注意,这与您在问题底部显示的代码不同,因为这只是声明 local 变量。如果您只 想要 局部变量,那很好 - 但如果您需要 instance 变量,则使用上述代码。
基本上,字段初始值设定项的功能有限。来自 C# 4 规范的第 10.5.5.2 节:
实例字段的变量初始化器不能引用正在创建的实例。因此,在变量初始化器中引用
this
是编译时错误,因为变量初始化器通过simple-name 引用任何实例成员是编译时错误。 p>
(“因此”和“因此”在我看来是错误的 - 通过简单名称引用成员是非法的因为它引用 this
- 我会 ping Mads关于它 - 但这基本上是相关部分。)
【讨论】:
是的,当前版本读起来像“由于我们在simple-name
s 上出现编译时错误,我们将引用 this
设为错误”,而不是相反。
@JonSkeet 出现这种行为的原因是字段在构造函数之前被初始化。因此,当您尝试初始化字段时,没有实例成员。这就是为什么在类被实例化之前你不能使用它们对吧?
@UfukSURMEN:不是真的......该对象已经存在,但它会引发一些非常难以解释的错误。 (诚然,有时这很烦人......)【参考方案2】:
即使初始化表达式保证在"textual order"中,对于实例字段初始化器to access the this
reference也是非法的,并且您在
Dinner dinner = repo.GetDinner(5);
相当于
Dinner dinner = this.repo.GetDinner(5);
恕我直言,最佳实践是将字段初始化保留为常量值或简单的new
语句。任何比这更复杂的东西都应该交给构造函数。
【讨论】:
以上是关于字段初始值设定项不能引用非静态字段、方法或属性?的主要内容,如果未能解决你的问题,请参考以下文章