为什么你不能在成员初始化器中使用'this'?

时间:2011-05-25 13:30:23

标签: c#

  

可能重复:
  Cannot use ‘this’ in member initializer?

如果我尝试做这样的事情,我会收到错误的任何想法:

public class Bar
{
    public Bar(Foo foo)
    {
    }
}

public class Foo
{
    private Bar _bar = new Bar(this);
}

我收到错误说:

“不能在成员初始化程序中使用'this'”

但以下工作:

public class Foo
{
    private Bar _bar;

    public Foo()
    {
        _bar = new Bar(this);
    }
}

有谁知道这背后的原因?我的理解是这些会编译成同一个IL,所以很好奇为什么一个被允许而另一个不被允许。

谢谢, 亚历

5 个答案:

答案 0 :(得分:52)

怀疑是为了防止你在至少基类构造函数运行之前使用该对象,确保所有基类成员都已正确初始化。 (变量初始化器在基类构造函数之前执行,而构造函数体在之后执行。)

当我接下来接近它时,将检查带注释的规范是否有任何关于此的说法......

编辑:C#4注释规范没有任何解释。只是(在10.5.5.2中):

  

实例字段的变量初始值设定项无法引用正在创建的实例。

答案 1 :(得分:14)

字段初始值设定项在基类构造函数之前运行,因此this尚不存在。它仅在基础构造函数完成执行后才存在。

17.10.2 Instance variable initializers

  

当实例构造函数没有时   构造函数初始化程序,或者它有一个   表单的构造函数初始值设定项   base(...),隐式构造函数   执行指定的初始化   通过变量初始化器   在其类中声明的实例字段。   这对应于一系列   已执行的分配   马上进入   构造函数和隐式之前   调用直接基类   构造函数。变量   初始化程序在。中执行   它们出现的文本顺序   班级宣言。

答案 2 :(得分:0)

我相信这是因为字段在类初始化之前初始化,所以当运行以下代码时:

private Bar _bar = new Bar(this);

“this”没有实际值可供参考。

虽然将它放在构造函数中意味着有一个“Foo”实例可以通过“this”引用

答案 3 :(得分:0)

在C#中,没有逻辑意图在方法'和属性'之外。

字段初始值设定项是一个例外,但有一些限制。

使用关键字获取当前对象的引用是错误的,因为类字段声明不是逻辑而是类设计,而是运行的一部分 - 时间语义。

顺便说一下,它似乎是一个C#设计决策,因为实际上,一个字段初始化程序在类构造期间运行,所以“声明类的当前实例”应该可以通过这个。但同样,在方法或属性体范围之外这个会是什么?

正如Jon Skeet和其他人指出的那样,这个不可用,因为字段初始化器是在基础构造函数执行后执行的。

答案 4 :(得分:0)

成员初始化程序在类构造函数之前运行。考虑一个类中可能有许多成员初始值设定项。

如果你在构造函数中使用'this' - >所有具有初始化程序的成员都已初始化。所以一切都很好。

如果在成员初始化程序中使用'this':其他成员(附加了初始化程序)可能尚未初始化 - > '这个'尚未准备好。这就是为什么不允许在这里使用'this'的原因。