C# Object Initialiser - Reference to the new instance

做~自己de王妃 提交于 2019-11-27 08:20:37

问题


Can I somehow get a reference to the instance I am creating using object initialiser

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

"this" should point to the new TestClass instance I'm creating. But it obviously refers the the instance of the class in which this code resides.

I'm not asking if this is a good way to do this. I'm aware that I can do this like this:

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

I have a complicated scenario, in which a reference to the new instance in the object initialiser would make life easier.

Is this possible in any way?


回答1:


There's no way around it, the C# specification explicitly says that "It is not possible for an object or collection initializer to refer to the object instance being initialized."

As for why it's impossible, I suspect that there's just no nice way to implement it. We want some syntactic sugar equivalent to

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

We just need a keyword to refer to temp within the initializer, but none is easily available. We can't use this because it already means something outside the initializer. Should SomeProperty = this.SomeMethod(this) be equivalent to temp.SomeProperty = this.SomeMethod(temp) or temp.SomeProperty = temp.SomeMethod(temp)? The second is consistent, but then what happens if we need the first?

We could try to use x, though we can only pick a name if the new object is immediately assigned to a variable. However, we now can't refer to the old value of x inside the initializer, doing the equivalent of temp.SomeProperty = SomeMethod(x).

We could reuse the value keyword from property setters. This sounds good since value already stands in for the missing parameter if you consider a property getter to be syntactic sugar for a set_SomeProperty(value) method. Using it to also refer to the missing variable in the object initializer looks promising. However, we could be creating this object inside a property setter, in which case value is already being used, and we need to be able to do temp.SomeProperty = SomeMethod(value).

It looks like we'll have to create a new keyword just for this purpose, maybe newthis. However, this is a breaking change to the language because any code that has a variable called newthis doesn't work any more. Microsoft generally needs a really good reason to introduce breaking changes, so it's better to forbid access to the object being initialized.




回答2:


No, you can't use the object initializer to assign the object you're creating somewhere else - that defeats the whole point of the object initializer. The x variable doesn't get assigned until after the object initializer is completed. You'll need to assign the object, then use it in a separate statement.

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



回答3:


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

Before the right part of this initialization is evaluated and executed, the reference to the new object is not yet made available to the code. That is done for security purposes, otherwise you could create some deadlock or endless loop with you code.




回答4:


Exposing or using an object that hasn't been fully constructed is usually a very bad idea. Consider the following:

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
     }
}

This is an extremely contrived example. Things can get a whole lot worse than this. The following was quite an interesting link regarding this issue: Partially Constructed Objects



来源:https://stackoverflow.com/questions/3564626/c-sharp-object-initialiser-reference-to-the-new-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!