4

我能否以某种方式获得对我正在使用对象初始化程序创建的实例的引用

var x = new TestClass
           {
                 Id = 1,
                 SomeProperty = SomeMethod(this)
           }

“this”应该指向我正在创建的新 TestClass 实例。但它显然是指这段代码所在的类的实例。

我不是在问这是否是一个好方法。我知道我可以这样做:

var x = new TestClass {Id= x};
x.SomeProperty = SomeMethod(this);

我有一个复杂的场景,其中对对象初始化程序中的新实例的引用会使生活更轻松。

这有可能吗?

4

4 回答 4

6

没有办法绕过它,C# 规范明确指出“对象或集合初始化程序无法引用正在初始化的对象实例。”

至于为什么不可能,我怀疑没有很好的方法来实现它。我们想要一些相当于的语法糖

var temp = new TestClass();
temp.Id = 1;
temp.SomeProperty = SomeMethod(temp);
x = temp;

我们只需要temp在初始化器中引用一个关键字,但没有一个是容易获得的。我们不能使用this,因为它已经意味着初始化程序之外的东西。应该SomeProperty = this.SomeMethod(this)等于temp.SomeProperty = this.SomeMethod(temp)or temp.SomeProperty = temp.SomeMethod(temp)?第二个是一致的,但是如果我们需要第一个会发生什么?

我们可以尝试使用x,但如果新对象立即分配给变量,我们只能选择一个名称。但是,我们现在不能引用x初始化器内部的旧值,相当于temp.SomeProperty = SomeMethod(x).

我们可以重用value属性设置器中的关键字。这听起来不错,因为value如果您认为属性 getter 是set_SomeProperty(value)方法的语法糖,它已经代表了缺少的参数。使用它来引用对象初始化器中缺失的变量看起来很有希望。但是,我们可以在属性设置器中创建这个对象,在这种情况下,value它已经被使用了,我们需要能够做到temp.SomeProperty = SomeMethod(value)

看起来我们必须为此目的创建一个新关键字,也许newthis. 但是,这是对语言的重大更改,因为任何具有变量调用的代码newthis都不再工作。Microsoft 通常需要一个非常好的理由来引入重大更改,因此最好禁止访问正在初始化的对象。

于 2010-08-25T10:37:36.637 回答
1

不,您不能使用对象初始化程序将您正在创建的对象分配到其他地方 - 这会破坏对象初始化程序的全部意义。在x对象初始化程序完成之前,不会分配变量。您需要分配对象,然后在单独的语句中使用它。

var x = new TestClass {
    Id = 1
};
x.SomeProperty = SomeMethod(x);
于 2010-08-25T09:53:54.900 回答
0

暴露或使用尚未完全构建的对象通常是一个非常糟糕的主意。考虑以下:

class Connection
{
    internal string connectionString;
    public Connection(ConnectionPool pool, string connectionString) {
        this.pool = pool;
        //this.connectionString = connectionString; // I moved it because I could.
        this.pool.Register(this);
        this.connectionString = connectionString;
        this.Init();        
    }

    private void Init() { //blah }
}

class ConnectionPool
{
     public void Register(Connection c)
     {
         if ( this.connStrings.Contains( c.connectionString ) ) // BOOM
     }
}

这是一个非常人为的例子。事情可能会比这更糟。以下是关于这个问题的一个非常有趣的链接: Partially Constructed Objects

于 2010-08-25T12:08:49.357 回答
-1
var x = new TestClass
           {
                 Id = 1,
                 SomeProperty = SomeMethod(this)
           }

在此初始化的正确部分被评估和执行之前,对新对象的引用尚未对代码可用。这样做是出于安全目的,否则您可能会使用代码创建一些死锁或无限循环。

于 2010-08-25T09:57:11.213 回答