C# &引用;这";直接初始化类成员变量时不可用

C# &引用;这";直接初始化类成员变量时不可用,c#,initialization,this,C#,Initialization,This,为什么编译器在定义实例变量时,在初始化实例变量时会给出一个关于该变量不可用的错误 关键字“this”在当前上下文中不可用 构造函数初始化很好。我理解这里的场景-我只是想找到构造函数可以使用“this”的原因(通过MSDN或其他方式),但如果初始化成员变量,则不能直接使用 这是我看到的错误的一个简单抽象 public class ClassA { // Gets compiler error that "this" unavailable protected ClassB _a1

为什么编译器在定义实例变量时,在初始化实例变量时会给出一个关于该变量不可用的错误

关键字“this”在当前上下文中不可用

构造函数初始化很好。我理解这里的场景-我只是想找到构造函数可以使用“this”的原因(通过MSDN或其他方式),但如果初始化成员变量,则不能直接使用

这是我看到的错误的一个简单抽象

public class ClassA
{
    // Gets compiler error that "this" unavailable
    protected ClassB _a1 = new ClassB(this);

    // Works fine
    protected ClassB _a2;
    public ClassA() { _a2 = new ClassB(this); }
}

public class ClassB
{
    public ClassA A { get; private set; }
    public ClassB(ClassA a) { this.A = a; } 
}
我希望将我的初始化保留在赋值旁边,因为上面的示例是我代码的抽象,我为10-15个成员变量定义了惰性valueFactory委托,其中委托需要将数据上下文作为参数传递给构造函数。对于15个成员变量,我更愿意将赋值放在定义旁边的一行,而不是15行定义,然后在构造函数中对每一行进行初始化

这基本上是我在实际代码中必须做的:

public class MyContext
{
    public ProgramService Programs { get { return _programs.Value; } }
    protected Lazy<ProgramService> _programs;

    public MyContext()
    {
        _programs = new Lazy<ProgramService>(() => new ProgramService(this));
    }
}
公共类MyContext
{
公共程序服务程序{get{return\u Programs.Value;}}
受保护的惰性程序;
公共MyContext()
{
_programs=newlazy(()=>newprogramservice(this));
}
}

基本上是为了防止您依赖order()和正在构造的类的可能不可用状态。我认为最重要的原则是,如果是“复杂”的逻辑,那么应该使用构造函数

例如,这样做:

class A {
   private int x = 1;
   private int y = this.x + 1;
}
将导致与以下不同的结果:

class A {
   private int y = this.x + 1;
   private int x = 1;
}
这有点出乎意料。为了避开这个问题,但仍然允许内联init的便利性-不允许
这使得排序无关紧要

在您的实际代码中,您可能会执行延迟检查以将内容放在一起:

public ProgramService Programs { 
   get { 
      if (_programs == null) _programs = new ProgramService(this);
      return _programs.Value; 
   } 
}
// change this to private to keep subclasses from accessing a possibly null reference
private Lazy<ProgramService> _programs;
公共程序服务程序{
获取{
如果(_programs==null)_programs=new ProgramService(this);
返回_programs.Value;
} 
}
//将其更改为private以防止子类访问可能为null的引用
私人懒惰计划;

是否有可能在构造函数得到你的问题的很好答案之前对字段进行初始化?E对你的问题给出了很好的答案:虽然现在我看到了,但michalk引用的问题可能更准确。@michalk-看起来Jon Skeet的答案正是原因-在注释的C#specs中没有指定原因,只是这是不可能的。您暗示初始化是自上而下完成的。这实际上是在什么地方定义的吗?@Ralf-link添加到spec(“变量初始值设定项是按照它们在类声明中出现的文本顺序执行的”)另外一件需要注意的事情是:只要调用任何构造函数,实例字段就会被初始化。。。这意味着它发生在调用超类的构造函数之前。