字段初始值设定项不能引用非静态字段、方法或属性?

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-names 上出现编译时错误,我们将引用 this 设为错误”,而不是相反。 @JonSkeet 出现这种行为的原因是字段在构造函数之前被初始化。因此,当您尝试初始化字段时,没有实例成员。这就是为什么在类被实例化之前你不能使用它们对吧? @UfukSURMEN:不是真的......该对象已经存在,但它会引发一些非常难以解释的错误。 (诚​​然,有时这很烦人......)【参考方案2】:

即使初始化表达式保证在"textual order"中,对于实例字段初始化器to access the this reference也是非法的,并且您在

中隐式使用它
Dinner dinner = repo.GetDinner(5); 

相当于

Dinner dinner = this.repo.GetDinner(5);

恕我直言,最佳实践是将字段初始化保留为常量值或简单的new 语句。任何比这更复杂的东西都应该交给构造函数。

【讨论】:

以上是关于字段初始值设定项不能引用非静态字段、方法或属性?的主要内容,如果未能解决你的问题,请参考以下文章

字段初始值设定项不能引用非静态字段、方法或属性

C# 字段初始值设定项无法引用非静态字段、方法或属性

C# 字段初始值设定项无法引用非静态字段、方法或属性

C# 字段初始值设定项无法引用非静态字段、方法或属性

C#变量初始化问题:字段初始值无法引用非静态字段方法或属性

[C#]变量初始化问题:字段初始值无法引用非静态字段方法或属性