2011-05-25 40 views
48

可能重复:
Cannot use ‘this’ in member initializer?为什么你不能在成员初始值设定项中使用'this'?

任何想法,为什么,如果我尝试做这样的事情,我得到一个错误:

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

我不知道为什么这个问题被关闭为重复,因为答案的另一个问题是,为什么它是错的,用“这是在编译器中的错误回答说:”没有实际没有被报道解释为什么它不被允许。 – Powerlord 2015-07-28 14:43:02

回答

52

嫌疑这是为了防止您在使用前至少基类的构造函数运行的对象,以确保所有的基类成员被适当地初始化。 (变量初始化被基类的构造函数之前执行,而构造体,经过执行

将检查标注的规格是否有什么说这个的时候,我下个吧..

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

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

+0

有趣,谢谢。从来没有意识到变量初始化器在基类之前运行... – AlexC 2011-05-25 15:48:03

+19

你当然是正确的。我们应该将其添加到下一版的带注释的规范中,这是一个很好的规范。 – 2011-05-25 16:43:35

+1

有VS建议将我的支持字段转换为'懒惰' – 2015-06-30 05:16:27

13

字段初始值设定项在基类构造函数之前运行,所以this尚不存在。只有基础构造函数完成执行后才存在。

17.10.2 Instance variable initializers

当一个实例构造函数没有 构造函数的初始化,或它的形式是 碱(...)的 构造函数的初始化,该构造隐式 执行初始化通过指定 在其类中声明的 实例字段的变量初始值设定项。 这对应于那些在进入到 构造立即与隐性 调用直接基类 构造之前执行 分配的序列。变量 初始值设定项以 文本顺序执行,它们在类声明中出现在 中。

+1

它存在 - 它只是没有完全初始化。 – 2011-05-25 13:35:05

0

我相信这是因为场初始化,然后初始化类所以运行下面的代码时:

private Bar _bar = new Bar(this); 

“这个”必须引用没有实际价值。

虽然把它在构造意味着存在“foo”的referencable的一个实例由“​​这个”

0

在C#,没有逻辑旨在是外部方式和属性机构。

字段初始化是个例外,但有一些限制。

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

顺便说一句,现在看来,这是一个C#设计决策, 因为,事实上,一个字段初始一流的施工过程中运行,所以“目前的声明类的实例”应该通过 可用。但是,再次, 以外的方法或属性体范围?

正如Jon Skeet和其他人指出的,这个不可用,因为字段初始值设定项是在基本构造函数执行后执行的。

+0

在方法或属性体外,它仍然是代码执行的上下文中的对象。如果它试图使用尚未被基类初始化的状态,那么它会使成员初始化器具有完美*感*。 – 2011-05-25 13:45:13

+0

绝对同意并感谢您的评论。这就是为什么我指出这是一个C#设计决策的事实,但我提出这个问题是因为我发现在这个范围内有** this **关键字会引起混淆(它可能很容易成为整个错误)。 – 2011-05-25 13:53:45

+0

IAS:但要注意,与*小*更改为C#,使之表现得更像Java(其中超类构造函数的变量初始化之前执行的)错误的因由会消失。我认为*从根本上*它是有道理的 - 只是有一些警告。 – 2011-05-25 13:55:05

0

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

如果使用“这”在构造函数 - >与初始化所有成员都初始化。所以一切都好。

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

相关问题