如果我尝试做这样的事情,我会收到错误的任何想法:
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,所以很好奇为什么一个被允许而另一个不被允许。
谢谢, 亚历
答案 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'的原因。