我可以以某种方式获取对我使用对象初始化器创建的实例的引用
var x = new TestClass
{
Id = 1,
SomeProperty = SomeMethod(this)
}
“this”应该指向我正在创建的新TestClass实例。但它显然是指代码所在的类的实例。
我不是在问这是否是一个很好的方法。 我知道我可以这样做:
var x = new TestClass {Id= x};
x.SomeProperty = SomeMethod(this);
我有一个复杂的场景,在对象初始化器中引用新实例会让生活更轻松。
这有可能吗?
答案 0 :(得分:5)
没有办法绕过它,C#规范明确地说"It is not possible for an object or collection initializer to refer to the object instance being initialized."
至于为什么这是不可能的,我怀疑没有很好的方法来实现它。我们想要一些相当于
的语法糖var temp = new TestClass();
temp.Id = 1;
temp.SomeProperty = SomeMethod(temp);
x = temp;
我们只需要一个关键字来引用初始化程序中的temp
,但没有一个可以轻易获得。我们不能使用this
,因为它已经意味着初始化程序之外的东西。 SomeProperty = this.SomeMethod(this)
应该等同于temp.SomeProperty = this.SomeMethod(temp)
还是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通常需要一个非常好的理由来引入重大更改,因此最好禁止访问正在初始化的对象。
答案 1 :(得分:1)
不,您不能使用对象初始值设定项来分配您在其他地方创建的对象 - 这会破坏对象初始值设定项的整个点。在完成对象初始化程序之后才会分配x
变量。您需要分配对象,然后在单独的语句中使用它。
var x = new TestClass {
Id = 1
};
x.SomeProperty = SomeMethod(x);
答案 2 :(得分:0)
var x = new TestClass
{
Id = 1,
SomeProperty = SomeMethod(this)
}
在评估和执行此初始化的右侧部分之前,对新代码的引用尚未可用于代码。这样做是为了安全起见,否则你可能会用代码创建一些死锁或无限循环。
答案 3 :(得分: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