For the first time i created a linq to sql classes
. I decided to look at the class and found this.
What... why is it doing if(sz !=sz2) { sz = sz2; }. I dont understand. Why isnt the set generated as this._Property1 = value
?
private 开发者_JS百科string _Property1;
[Column(Storage="_Property1", CanBeNull=false)]
public string Property1
{
get
{
return this._Property1;
}
set
{
if ((this._Property1 != value))
{
this._Property1 = value;
}
}
}
It only updates the property if it has changed. This is probably based on the assumption that a comparison is cheaper than updating the reference (and all the entailed memory management) that might be involved.
Where are you seeing that? The usual LINQ-to-SQL generated properties look like the following:
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();
}
}
}
And now it's very clear that the device is to avoid sending property changing/changed notifications when the property is not actually changing.
Now, it turns out that OnProperty1Changing
and OnProperty1Changed
are partial
methods so that if you don't declare a body for them elsewhere the calls to those methods will not be compiled into the final assembly (so if, say, you were looking in Reflector you would not see these calls). But SendPropertyChanging
and SendPropertyChanged
are protected
methods that can't be compiled out.
So, did you perhaps change a setting that prevents the property changing/changed notifications from being emitted by the code generator?
Setting a field won't cause property change notifications, so that's not the reason.
I would guess that this design choice was driven by something like the following:
That string is an immutable reference type. Therefore the original and new instances are interchangeable. However the original instance may have been around longer and on average may therefore be slightly more expensive to collect (*). So performance may be better if the original instance is retained rather than being replaced by a new identical instance.
(*) The new value has in most cases only just been allocated, and won't be reused after the property is set. So it is very often a Gen0 object that is efficient to collect, whereas the original value's GC generation is unknown.
If this reasoning is correct, I wouldn't expect to see the same pattern for value-type properties (int, double, DateTime, ...).
But of course this is only speculation and I may be completely wrong.
Looks like there's persistence going on here. If something is using reflection (or a pointcut, or something) to create a SQL UPDATE
query when _Property1 changes, then it'll be very much more expensive to update the field than to do the comparison.
It comes from Heijlsberg's ObjectPascal root.... at least that's how most of the Borland Delphi VCL is implemented... ;)
精彩评论