Using IsValueCreated before accessing LazyLoadObject.Value - c#

I'm working with some C# code that's using .Net 4 Lazy loads and I'm not super familiar with it. I'm trying to figure out if this particular code is useless or not.
Originally the property and code below where in the same class, but now I've moved the code to an external class that no longer has access to the private "lazyRecords" property. I'm wondering what the point of checking "lazyRecords.IsValueCreated" is since the lazyRecords.Value has not been invoked yet, wouldn't it always be false? Or is it checking to see if another thread somehow invoked the Value? Or is it doing this in case of a thread exception that resulted in not loading the object?
Property:
private Lazy<List<Record>> lazyRecords;
public List<Record> Records
{
get
{
return lazyRecords.Value;
}
set
{
lazyRecords = new Lazy<List<Record>>(() => value);
}
}
Code:
public Category LoadCategory(BaseClient client)
{
Category category = new Category();
category.Records = client.RecordClient.GetRecordsByCategoryID(category.ID);
if (lazyRecords.IsValueCreated)
{
category.WorldRecord = category.Records.FirstOrDefault();
}
else
{
category.WorldRecord = client.RecordClient.GetWorldRecord(category.ID);
}
}

The code is pretty useless, yes. To help you understand why, consider this very minimal version of Lazy (the real class has more options and logic to take care of multiple threads, but this is the rough idea):
public class Lazy<T>
{
private readonly Func<T> _creator;
private T _cachedValue;
public Lazy(Func<T> creator) => _creator = creator;
public bool IsValueCreated { get; private set; }
public T Value
{
get
{
if (!IsValueCreated)
{
_cachedValue = _creator();
IsValueCreated = true;
}
return _cachedValue;
}
}
}
The delegate passed to the constructor is called on demand, the first time the Value is requested. In the code you've posted there is no point to this because the delegate simply returns the value passed into the setter.
As to the LoadCategory method, the code you posted is hard to decipher. It directly accesses lazyRecords, implying it's a method of the same class. But then it accesses Records on a different object.

Related

What is the difference between returning a value inside a get, and assigning the property?

If I wanted to keep this handy for non async methods that return task.
public static Task CompletedTaskA { get { return Task.CompletedTask; } }
public static Task CompletedTaskB { get; } = Task.CompletedTask;
Should one be preferred over the other for any kind of context? Or are they the same? I also wonder the same with strings and basically anything i do with properties ie:
get {return "some string"; } vs { get; } = "some string";
EDIT: I would like to clarify my usage of the above prop. I have several event handlers which have Task as a return type, offered to me by a library i'm using. an example of one such event:
private Task Client_MessageReceived(Message message)
{
Task.Run(async ()=> await HandleMessageReceived(message));
// here is where i would use it
return CompletedTask; // A OR B?
}
private async Task HandleMessageReceived(Message message)
{
// Do stuff with message that might take long and block the handler
}
My intention is to save a completed task in a field (i'm choosing a readonly property in this case) and just keep using it to satisfy the task return. I am wondering if one of the above examples, keeps using the same completed task, and the other one keeps asking for another completed task every time?
If you go to SharpLab and look at the code for:
public class C
{
public void M()
{
}
public string Greetig_1
{
get{return "hello";}
}
public string Greeting_2{get;} = "hello";
}
You can see that Greeting_2 is backed by a member variable:
public class C
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string <Greeting_2>k__BackingField = "hello";
public string Greeting_1
{
get
{
return "hello";
}
}
public string Greeting_2
{
[CompilerGenerated]
get
{
return <Greeting_2>k__BackingField;
}
}
public void M()
{
}
}
This follows through to the IL level. As Greeting_2 is backed by a member variable that variable is initialized in the constructor.
In your example with Task.CompletedTask what you end up with is:
public static Task CompletedTaskB { get; } = Task.CompletedTask;
Caching the Task, whereas:
public static Task CompletedTaskA { get { return Task.CompletedTask; } }
Make a call to get the CompletedTask object in Task each time. In reality this will be inline by the JIT. The approach also has the advantage of not adding an additional (hidden) member variable to your class, which may be an issue if you've got lots of instances and are concerned about memory usage.
They are not the same.
A properties get method is called every time you access it. By default when you create a property, it will have a hidden field behind it so:
public static Task CompletedTaskB { get; set; }
will actually generate this behind the scenes:
private static Task _completedTaskB;
public static Task CompletedTaskB
{
get {
return _completedTaskB;
}
set {
_completedTaskB = value;
}
}
When you assign the property = Task.CompletedTask, you are setting its initial value which is equivalent to :
_completedTaskB = Task.CompletedTask;
When you then access the property, it will read from the private field.
I notice though that you are defining this as readonly (only a getter not a setter) so you will not be able to assign the variable. Instead you will have to use:
public static Task CompletedTaskA { get { return Task.CompletedTask; } }
This will return Task.CompletedTask all the time.
In general the difference between:
{ get; set; } = "some string";
and
get {return "some string"; }
is that the first is an initial assignment whereas the latter is a method that is called whenever you access the property.
When you assign a value to the property right at the definition, some "magic" happens behind the scenes.
The compiler creates a hidden backing field, and the value is assigned to that backing field in the constructor of the class.
In other words, you can think of the two classes below as working the same way.
class AssignedImplicit {
public string Prop {get;} = "example";
}
class AssignedExplicit {
private readonly string Prop_BackingField;
public AssignedExplicit() {
Prop_BackingField = "example";
}
public string Prop { get { return Prop_BackingField; } }
}
When you just define a get method without assigning, the backing field is not created, and no work is added to the constructor.
This is true for strings, or for any other type.
If you assign a value to the property, the work of constructing/fetching that value is put into the constructor of your class. If you create the value in the get method, then the work is put into the get method.

How to reset delegate to original code

given this delegate
public class XYZ
{
public static Action<Profile> DoSomething = (profile) =>
{
//some default code here
return;
};
}
at some time in my main execution I override it with this:
XYZ.DoSomething = (currProfile) =>
{
// some overriding code here
}
How do I set the code back to the original default code when I need to without duplicating code?
Here's a good reason to never use public fields...
Once you set it; its gone. You can hold onto the original value though:
var originalAction = XYZ.DoSomething;
XYZ.DoSomething = ...;
XYZ.DoSomething = originalAction;
Usually it is a bad idea to rely on client code to handle this however; so if I was writing it I would expose as a property like so:
public Action<X> DoSomethingOverride {get; set;}
public Action<X> DoSomething => doSomethingOverride ?? DefaultMethod;
private void DefaultMethod (X param)
{
}
There are a number of other ways to handle this, but all involve storing off the original method. All good ways to handle this will use a property to ensure that only the declaring class is actually setting the DoSomething method and that resetting to the default is possible.
Total aside; since this is static setting the action will affect everything that uses this class. This is asking for bugs later; don't do that.
Maybe somthing like this?
public static Action<Profile> _doSomethingBase = (profile) =>
{
//some default code here
return;
};
public static Action<Profile> _doSomething = _doSomethingBase;
public static Action<Profile> DoSomething
{
get => _doSomething;
set => _doSomething = value;
}
public static void RevertDoSomething()
{
DoSomething = _doSomethingBase;
}

Is this good way of using .NET's System.Lazy

private Lazy<Image> _headshot = new Lazy<Image>(LoadHeadshotFromHDD);
public Image Headshot
{
get
{
return _headshot.Value;
}
set
{
_headshot = new Lazy<Image>(() => value);
}
}
Let's say I have a Person class and Headshot property is in that class. Headshot is loaded from HDD so I want it to be lazy, but I also want to implement setter for that property. Will there be a problem with the way that I've implemented this? I'm just not sure that I'm using it correctly.
There's really no point in using lazy loading if you already have the object in memory (in the setter case), but it's perfectly fine to do it this way. One thing I can think of, is if you'd check the _headshot.IsValueCreated, it'll return false, even though you already have the object in memory. Another alternative would be
private Image _headshot;
public Image Headshot
{
get { return _headshot ?? (_headshot = LoadHeadshotFromHDD()); }
set { _headshot = value; }
}
This will lazy load the headshot when the property is accessed, just like when using Lazy<T>, but it'll set the value directly, so you can check _headshot != null instead of _headshot.IsValueCreated. You should check out Jon Skeet's Singleton Pattern post.
Looks ok, however, if you'd take the initialization to the constructor, you could have less code.
public class Foo
{
public Foo()
{
this.Headshot = new Lazy<Image>( () => LoadHeadshotFromHDD );
}
public Lazy<Image> Headshot { get; set; }
}

How to avoid private property null check to do lazy loading?

I have a class with like 20 fields which get populated from SQL database on load. Currently I am calling load data method right after the constructor, which calls SQL proc and populate all the required fields. At times, I may not access the these 20 fields at all, I am adding additional cost of SQL call even though it was not required. So I changed all the properties to have an associated private property and when the program calls the public property, first I check the private property and if it is null that means we need to load data from sql so I call the load method. It works great, but when I see the code, there is a repeated pattern of null check and load the sql query. Is there a better way of doing this?
private string _name;
public string Name
{
get {
if (_name == null)
LoadData(); //this popultes not just but all the properties
return _name;
}
}
Btw C# now has default lazy-loaders implementation. Why not to use it, instead of providing isSomethingLoaded flags? :)
public class Bar
{
private Lazy<string> _name = new Lazy<string>(() => LoadString());
public string Name
{
get { return _name.Value; }
}
}
In case of non-static LoadString method, lazy-loader should be initialized in constructor;
Nope, this is right. Here is the wikipedia article. The overhead of the null check will be very minimal compared to unnecessary database calls. Now, if the users of the program actually use the values 99% of the time, then I would say this pattern is not needed.
Just one note of caution: If any of your values could possibly be null, then you will make unnecessary database calls. It might be better to do something like this (which will be an even quicker check since it is just a bit check):
//Constructor default to not loaded
bool isLoaded = false;
private string _name;
public string Name
{
get {
if (!isLoaded)
LoadData(); //this popultes not just but all the properties
return _name;
}
}
private LoadData()
{
//Load Data
isLoaded = true;
}
Well you could change it to:
if (!initialized)
LoadData();
And in your LoadData set initialized to true, but that really doesn't change the semantics of it.
One thing you can do is to extract if into separate method so each property contains just one additional call:
void EnsureData()
{
if (!dataLoaded)
LoadData(); //this populates all the properties
}
public string Name {
get {
EnsureData();
return _name;
}
}
I think you should consider your application structure. Why would you even instantiate the class if you are not going to be using the properties? I believe it's actually cleaner for you to call the SQL after your constructor code but only create the objects of your class if you are going to be using it. The other more flexible solution is making the LoadData public and calling it as needed from the object instance as needed.
I am in the learning process of design patterns. i have one suggestion if you load data only once you can try with singleton design pattern.
public class Singleton123
{
private static readonly string _property1 = ClassLoadData.LoadData();
public static string MyProperty1
{
get
{
return _property1;
}
}
}
public class ClassLoadData
{
public static string LoadData()
{
// any logic to load data
return "test";
}
}
Call property as below
Singleton123 obj = new Singleton123();
string stra = Singleton123.MyProperty1;
string strb = Singleton123.MyProperty1;
this property will be loaded only once.

c# marking class property as dirty

The following is a simple example of an enum which defines the state of an object and a class which shows the implementation of this enum.
public enum StatusEnum
{
Clean = 0,
Dirty = 1,
New = 2,
Deleted = 3,
Purged = 4
}
public class Example_Class
{
private StatusEnum _Status = StatusEnum.New;
private long _ID;
private string _Name;
public StatusEnum Status
{
get { return _Status; }
set { _Status = value; }
}
public long ID
{
get { return _ID; }
set { _ID = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
when populating the class object with data from the database, we set the enum value to "clean". with the goal of keeping most of the logic out of the presentation layer, how can we set the enum value to "dirty" when a property is changed.
i was thinking something along the lines of;
public string Name
{
get { return _Name; }
set
{
if (value != _Name)
{
_Name = value;
_Status = StatusEnum.Dirty;
}
}
}
in the setter of each property of the class.
does this sound like a good idea, does anyone have any better ideas on how the dirty flag can be assigned without doing so in the presentation layer.
When you really do want a dirty flag at the class level (or, for that matter, notifications) - you can use tricks like below to minimise the clutter in your properties (here showing both IsDirty and PropertyChanged, just for fun).
Obviously it is a trivial matter to use the enum approach (the only reason I didn't was to keep the example simple):
class SomeType : INotifyPropertyChanged {
private int foo;
public int Foo {
get { return foo; }
set { SetField(ref foo, value, "Foo"); }
}
private string bar;
public string Bar {
get { return bar; }
set { SetField(ref bar, value, "Bar"); }
}
public bool IsDirty { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T>(ref T field, T value, string propertyName) {
if (!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
IsDirty = true;
OnPropertyChanged(propertyName);
}
}
protected virtual void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You might also choose to push some of that into an abstract base class, but that is a separate discussion
One option is to change it on write; another is to keep a copy of all the original values and compute the dirtiness when anyone asks for it. That has the added benefit that you can tell exactly which fields have changed (and in what way) which means you can issue minimal update statements and make merge conflict resolution slightly easier.
You also get to put all the dirtiness-checking in one place, so it doesn't pollute the rest of your code.
I'm not saying it's perfect, but it's an option worth considering.
If you want to implement it in this way, and you want to reduce the amount of code, you might consider applying Aspect Oriented Programming.
You can for instance use a compile-time weaver like PostSharp , and create an 'aspect' that can be applied to properties. This aspect then makes sure that your dirty flag is set when appropriate.
The aspect can look like this:
[Serializable]
[AttributeUsage(AttributeTargets.Property)]
public class ChangeTrackingAttribute : OnMethodInvocationAspect
{
public override void OnInvocation( MethodInvocationEventArgs e )
{
if( e.Delegate.Method.ReturnParameter.ParameterType == typeof(void) )
{
// we're in the setter
IChangeTrackable target = e.Delegate.Target as IChangeTrackable;
// Implement some logic to retrieve the current value of
// the property
if( currentValue != e.GetArgumentArray()[0] )
{
target.Status = Status.Dirty;
}
base.OnInvocation (e);
}
}
}
Offcourse, this means that the classes for which you want to implement ChangeTracking, should implement the IChangeTrackable interface (custom interface), which has at least the 'Status' property.
You can also create a custom attribute ChangeTrackingProperty, and make sure that the aspect that has been created above, is only applied to properties that are decorated with this ChangeTrackingProperty attribute.
For instance:
public class Customer : IChangeTrackable
{
public DirtyState Status
{
get; set;
}
[ChangeTrackingProperty]
public string Name
{ get; set; }
}
This is a little bit how I see it.
You can even make sure that PostSharp checks at compile-time whether classes that have properties that are decorated with the ChangeTrackingProperty attribute, implement the IChangeTrackable interface.
This method is based on a set of different concepts provided in this thread. I thought i'd put it out there for anyone that is looking for a way to do this cleanly and efficiently, as i was myself.
The key of this hybrid concept is that:
You don't want to duplicate the data to avoid bloating and resource hogging;
You want to know when the object's properties have changed from a given original/clean state;
You want to have the IsDirty flag be both accurate, and require little processing time/power to return the value; and
You want to be able to tell the object when to consider itself clean again. This is especially useful when building/working within the UI.
Given those requirements, this is what i came up with, and it seems to be working perfectly for me, and has become very useful when working against UIs and capturing user changes accurately. I have also posted an "How to use" below to show you how I use this in the UI.
The Object
public class MySmartObject
{
public string Name { get; set; }
public int Number { get; set; }
private int clean_hashcode { get; set; }
public bool IsDirty { get { return !(this.clean_hashcode == this.GetHashCode()); } }
public MySmartObject()
{
this.Name = "";
this.Number = -1;
MakeMeClean();
}
public MySmartObject(string name, int number)
{
this.Name = name;
this.Number = number;
MakeMeClean();
}
public void MakeMeClean()
{
this.clean_hashcode = this.Name.GetHashCode() ^ this.Number.GetHashCode();
}
public override int GetHashCode()
{
return this.Name.GetHashCode() ^ this.Number.GetHashCode();
}
}
It's simple enough and addresses all of our requirements:
The data is NOT duplicated for the dirty check...
This takes into account all property changes scenarios (see scenarios below)...
When you call the IsDirty property, a very simple and small Equals operation is performed and it is fully customizable via the GetHashCode override...
By calling the MakeMeClean method, you now have a clean object again!
Of course you can adapt this to encompass a bunch of different states... it's really up to you. This example only shows how to have a proper IsDirty flag operation.
Scenarios
Let's go over some scenarios for this and see what comes back:
Scenario 1
New object is created using empty constructor,
Property Name changes from "" to "James",
call to IsDirty returns True! Accurate.
Scenario 2
New object is created using paramters of "John" and 12345,
Property Name changes from "John" to "James",
Property Name changes back from "James" to "John",
Call to IsDirty returns False. Accurate, and we didn't have to duplicate the data to do it either!
How to use, a WinForms UI example
This is only an example, you can use this in many different ways from a UI.
Let's say you have a two forms ([A] and [B]).
The first([A]) is your main form, and the second([B]) is a form that allows the user to change the values within the MySmartObject.
Both the [A] and the [B] form have the following property declared:
public MySmartObject UserKey { get; set; }
When the user clicks a button on the [A] form, an instance of the [B] form is created, its property is set and it is displayed as a dialog.
After form [B] returns, the [A] form updates its property based on the [B] form's IsDirty check. Like this:
private void btn_Expand_Click(object sender, EventArgs e)
{
SmartForm form = new SmartForm();
form.UserKey = this.UserKey;
if(form.ShowDialog() == DialogResult.OK && form.UserKey.IsDirty)
{
this.UserKey = form.UserKey;
//now that we have saved the "new" version, mark it as clean!
this.UserKey.MakeMeClean();
}
}
Also, in [B], when it is closing, you can check and prompt the user if they are closing the form with unsaved changes in it, like so:
private void BForm_FormClosing(object sender, FormClosingEventArgs e)
{
//If the user is closing the form via another means than the OK button, or the Cancel button (e.g.: Top-Right-X, Alt+F4, etc).
if (this.DialogResult != DialogResult.OK && this.DialogResult != DialogResult.Ignore)
{
//check if dirty first...
if (this.UserKey.IsDirty)
{
if (MessageBox.Show("You have unsaved changes. Close and lose changes?", "Unsaved Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
e.Cancel = true;
}
}
}
As you can see from the examples above, this can be a very useful thing to have since it really streamlines the UI.
Caveats
Every time you implement this, you have to customize it to the object you're using. E.g.: there's no "easy" generic way of doing this without using reflection... and if you use reflection, you lose efficiency, especially in large and complex objects.
Hopefully this helps someone.
Take a look at PostSharp (http://www.postsharp.org/).
You can easily create a Attribute which marks it as dirty you can add the attrubute to each property that needs it and it keeps all your code in one place.
Roughly speaking Create an interface which has your status in make the class implement it.
Create an attribute which can be applied on properties and cast to your interface in order to set the value when something changes one of the marked properties.
Your approach is basically how I would do it. I would just
remove the setter for the Status property:
public StatusEnum Status
{
get { return _Status; }
// set { _Status = value; }
}
and instead add a function
public SetStatusClean()
{
_Status = StatusEnum.Clean;
}
As well as SetStatusDeleted() and SetStatusPurged(), because I find it better indicates the intention.
Edit
Having read the answer by Jon Skeet, I need to reconsider my approach ;-) For simple objects I would stick with my way, but if it gets more complex, his proposal would lead to much better organised code.
If your Example_Class is lightweight, consider storing the original state and then comparing the current state to the original in order to determine the changes. If not your approach is the best because stroing the original state consumes a lot of system resources in this case.
Apart from the advice of 'consider making your type immutable', here's something I wrote up (and got Jon and Marc to teach me something along the way)
public class Example_Class
{ // snip
// all properties are public get and private set
private Dictionary<string, Delegate> m_PropertySetterMap;
public Example_Class()
{
m_PropertySetterMap = new Dictionary<string, Delegate>();
InitializeSettableProperties();
}
public Example_Class(long id, string name):this()
{ this.ID = id; this.Name = name; }
private void InitializeSettableProperties()
{
AddToPropertyMap<long>("ID", value => { this.ID = value; });
AddToPropertyMap<string>("Name", value => { this.Name = value; });
}
// jump thru a hoop because it won't let me cast an anonymous method to an Action<T>/Delegate
private void AddToPropertyMap<T>(string sPropertyName, Action<T> setterAction)
{ m_PropertySetterMap.Add(sPropertyName, setterAction); }
public void SetProperty<T>(string propertyName, T value)
{
(m_PropertySetterMap[propertyName] as Action<T>).Invoke(value);
this.Status = StatusEnum.Dirty;
}
}
You get the idea.. possible improvements: Use constants for PropertyNames & check if property has really changed.
One drawback here is that
obj.SetProperty("ID", 700); // will blow up int instead of long
obj.SetProperty<long>("ID", 700); // be explicit or use 700L
Here is how i do it.
In cases where i do not need to test for specific fields being dirty,
I have an abstract class:
public abstract class SmartWrap : ISmartWrap
{
private int orig_hashcode { get; set; }
private bool _isInterimDirty;
public bool IsDirty
{
get { return !(this.orig_hashcode == this.GetClassHashCode()); }
set
{
if (value)
this.orig_hashcode = this.orig_hashcode ^ 108.GetHashCode();
else
MakeClean();
}
}
public void MakeClean()
{
this.orig_hashcode = GetClassHashCode();
this._isInterimDirty = false;
}
// must be overridden to return combined hashcodes of fields testing for
// example Field1.GetHashCode() ^ Field2.GetHashCode()
protected abstract int GetClassHashCode();
public bool IsInterimDirty
{
get { return _isInterimDirty; }
}
public void SetIterimDirtyState()
{
_isInterimDirty = this.IsDirty;
}
public void MakeCleanIfInterimClean()
{
if (!IsInterimDirty)
MakeClean();
}
/// <summary>
/// Must be overridden with whatever valid tests are needed to make sure required field values are present.
/// </summary>
public abstract bool IsValid { get; }
}
}
As well as an interface
public interface ISmartWrap
{
bool IsDirty { get; set; }
void MakeClean();
bool IsInterimDirty { get; }
void SetIterimDirtyState();
void MakeCleanIfInterimClean();
}
This allows me to do partial saves, and preserve the IsDirty state if there is other details to save. Not perfect, but covers a lot of ground.
Example of usage with interim IsDirty State (Error wrapping and validation removed for clarity):
area.SetIterimDirtyState();
if (!UpdateClaimAndStatus(area))
return false;
area.MakeCleanIfInterimClean();
return true;
This is good for most scenarios, however for some classes i want to test for each field with a backing field of original data, and either return a list of changes or at least an enum of fields changed.
With an enum of fields changed i can then push that up through a message chain for selective update of fields in remote caches.
You could also think about boxing your variables, which comes at a performance cost, but also has its merits. It is pretty consise and you cannot accidentally change a value without setting your dirty status.
public class Variable<T>
{
private T _value;
private readonly Action<T> _onValueChangedCallback;
public Variable(Action<T> onValueChangedCallback, T value = default)
{
_value = value;
_onValueChangedCallback = onValueChangedCallback;
}
public void SetValue(T value)
{
if (!EqualityComparer<T>.Default.Equals(_value, value))
{
_value = value;
_onValueChangedCallback?.Invoke(value);
}
}
public T GetValue()
{
return _value;
}
public static implicit operator T(Variable<T> variable)
{
return variable.GetValue();
}
}
and then hook in a callback that marks your class as dirty.
public class Example_Class
{
private StatusEnum _Status = StatusEnum.New;
private Variable<long> _ID;
private Variable<string> _Name;
public StatusEnum Status
{
get { return _Status; }
set { _Status = value; }
}
public long ID => _ID;
public string Name => _Name;
public Example_Class()
{
_ID = new Variable<long>(l => Status = StatusEnum.Dirty);
_Name = new Variable<string>(s => Status = StatusEnum.Dirty);
}
}
Another method is to override the GetHashCode() method to somthing like this:
public override int GetHashCode() // or call it GetChangeHash or somthing if you dont want to override the GetHashCode function...
{
var sb = new System.Text.StringBuilder();
sb.Append(_dateOfBirth);
sb.Append(_marital);
sb.Append(_gender);
sb.Append(_notes);
sb.Append(_firstName);
sb.Append(_lastName);
return sb.ToString.GetHashCode();
}
Once loaded from the database, get the hash code of the object. Then just before you save check if the current hash code is equal to the previous hash code. if they are the same, don't save.
Edit:
As people have pointed out this causes the hash code to change - as i use Guids to identify my objects, i don't mind if the hashcode changes.
Edit2:
Since people are adverse to changing the hash code, instead of overriding the GetHashCode method, just call the method something else. The point is detecting a change not whether i use guids or hashcodes for object identification.

Categories