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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…