如果(sz!= sz2)sz = sz2,为什么这个代码会这样做?

时间:2009-12-20 07:47:08

标签: c# linq-to-sql

我第一次创建linq to sql classes。我决定看一下这节课并找到了。

什么......如果(sz!= sz2){sz = sz2; }。我不明白为什么生成的集不是this._Property1 = value

    private string _Property1;
    [Column(Storage="_Property1", CanBeNull=false)]
    public string Property1
    {
        get
        {
            return this._Property1;
        }
        set
        {
            if ((this._Property1 != value))
            {
                this._Property1 = value;
            }
        }
    }

5 个答案:

答案 0 :(得分:5)

只有在更改后才会更新属性。这可能是基于这样的假设:比较比更新可能涉及的引用(以及所有需要的内存管理)更便宜。

答案 1 :(得分:4)

你在哪里看到的?通常的LINQ-to-SQL生成的属性如下所示:

private string _Property1;
[Column(Storage="_Property1", CanBeNull=false)]
public string Property1 {
    get {
        return this._Property1;
    }
    set {
        if ((this._Property1 != value)) {
           this.OnProperty1Changing(value);
           this.SendPropertyChanging();
           this._Property1 = value;
           this.SendPropertyChanged("Property1");
           this.OnProperty1Changed();
       }
    }
}

现在非常清楚该设备是在物业实际没有变化时避免发送属性更改/更改通知。

现在,事实证明OnProperty1ChangingOnProperty1Changedpartial方法,因此如果你没有在别处为它们声明一个主体,那么对这些方法的调用将不会编译成最后的组装(所以,如果你正在寻找Reflector,你就不会看到这些电话)。但SendPropertyChangingSendPropertyChanged是无法编译出来的protected方法。

那么,您是否更改了阻止代码生成器发出属性更改/更改通知的设置?

答案 2 :(得分:3)

设置字段不会导致属性更改通知,因此不是原因。

我猜这个设计选择是由以下内容驱动的:

该字符串是不可变的引用类型。因此,原始实例和新实例是可互换的。然而,原始实例可能已经存在更长时间并且因此平均而言可能稍微更昂贵(*)。因此,如果保留原始实例而不是被新的相同实例替换,性能可能会更好。

(*)在大多数情况下,新值仅被分配,并且在设置属性后不会重复使用。因此,通常Gen0对象的收集效率很高,而原始值的GC生成是未知的。

如果这个推理是正确的,我不希望看到值类型属性(int,double,DateTime,...)的相同模式。

但当然这只是猜测,我可能完全错了。

答案 3 :(得分:0)

看起来这里有持久性。如果在_Property1发生变化时某些东西正在使用反射(或切入点或其他东西)来创建SQL UPDATE查询,那么更新字段比进行比较要贵得多。

答案 4 :(得分:0)

它来自Heijlsberg的ObjectPascal根......至少是大多数Borland Delphi VCL的实现方式......;)