【问题标题】:"this" is unavailable when directly initializing class member variable [duplicate]直接初始化类成员变量时“this”不可用[重复]
【发布时间】:2015-07-28 14:26:10
【问题描述】:

为什么在定义实例变量时,编译器会在初始化实例变量时给出 this 不可用的错误?

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

构造函数初始化没问题。我了解这里的情况 - 我只是想找到原因(通过 MSDN 或其他方式)为什么“this”可用于构造函数,但如果初始化成员变量则不能直接使用。

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

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 行定义中,然后在构造函数中再用 15 行来初始化每个变量。

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

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

    public MyContext()
    {
        _programs = new Lazy<ProgramService>(() => new ProgramService(this));
    }
}

【问题讨论】:

  • 是否有可能在构造函数被命中之前初始化字段
  • 你的问题的答案很好:stackoverflow.com/questions/6125247/…
  • 虽然现在我看了一下,michalk references的问题可能更准确。
  • @michalk - 看起来 Jon Skeet 的答案正是原因 - 在带注释的 C# 规范中没有指定原因,只是不可能。

标签: c# initialization this


【解决方案1】:

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

例如,这样做:

class A {
   private int x = 1;
   private int y = this.x + 1;
}

会导致不同的结果:

class A {
   private int y = this.x + 1;
   private int x = 1;
}

这有点出乎意料。为了回避这个问题,但仍然允许内联初始化的便利 - 不允许 this 使排序无关紧要。

在您的实际代码中,您可能会做一个惰性检查以将所有内容放在一起:

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;

【讨论】:

  • 您暗示初始化是自上而下完成的。这实际上是在某个地方定义的吗?
  • @Ralf - 添加到规范的链接(“变量初始化器按照它们在类声明中出现的文本顺序执行”)
  • 还有一点需要注意:只要调用任何构造函数,就会初始化实例字段...这意味着它发生在对超类的构造函数的任何调用之前。
猜你喜欢
  • 2020-05-15
  • 2023-03-24
  • 2011-11-02
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
相关资源
最近更新 更多