在设置单个属性时不能设置级联属性

本文关键字:设置 属性 级联 不能 单个 | 更新日期: 2023-09-27 18:10:47

下面的代码没有设置该属性。它什么都不做,在调试时直接跳转,即使使用F11

job.TDataReference.CheckedOut = false;

job的类型是TJob一个我自己用属性构建的类:

public TDataReference TDataReference
{
    get
    {
        return new TDataReference(this.DataReference);
    }
    set { this.tDataReference = value; }
}

TDataReference也是我自己用属性创建的一个类:

public bool CheckedOut
{
    get { return (dataRow[CHECKEDOUT].ToString() == "True"); }
    set { dataRow[CHECKEDOUT] = value.ToString(); }
}

and和dataRow类型的私有成员dataRow

有趣的是,下面的代码工作正常,并设置属性:

TDataReference dr = job.TDataReference;
dr.CheckedOut = false;

谁能给我解释一下。



非常感谢你的回答!我理解这个问题。:)

tDataReference依赖于this中的值。所以tDataReference最早可以被设置的时间是。datreference是已知的。你觉得改成这样怎么样?

private TDataReference tDataReference;
public TDataReference TDataReference
{
    get
    {
    if(tDataReference == null | tDataReference.Id != this.DataReference)
    {
        this.tDataReference = new TDataReference(this.DataReference);
    }        
    return this.tDataReference 
    }
    set { this.tDataReference = value; }
}

和设置级联属性工作吗??

在设置单个属性时不能设置级联属性

每次调用属性getter时都会创建一个新的实例。这段代码:

job.TDataReference.CheckedOut = false; // here you setting CheckedOut for the 1st instance of TDataReference
job.TDataReference.CheckedOut = false; // here you setting CheckedOut for the 2nd instance of TDataReference

与下面的伪代码类似:

var tDataRef1 = new TDataReference(job.DataReference);
tDataRef1.CheckedOut = false;
var tDataRef2 = new TDataReference(job.DataReference);
tDataRef2.CheckedOut = false;

你不应该这样写属性,这违反了设计准则。考虑这个条件的结果:

job.TDataReference == job.TDataReference // false, ooops...

要避免这种情况,可以这样修改属性:

public TDataReference TDataReference
{
    get
    {
        return tDataReference;
    }
    set { this.tDataReference = value; }
}
// field initialization is optional here, you can omit it 
// or make lazy initialization in getter like this: 
// return tDataReference ?? (tDataReference = new TDataReference(this.DataReference));
private TDataReference tDataReference = new TDataReference(this.DataReference);