473,382 Members | 1,386 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

State of Object changed or not

Hi All,
i do have a customer table in the Customer class i do have a
function which fetches data from the table and assign to the customer
properties,

Ok, In the Front end , i get all these properties and show it to the
web form controls.

There is a save&continue button in the form, There are chances that
none of the values will be modified , At this time i dont want the
Modify function to be called unnececerilly,

Can any one suggest how do i do it?
Regards

thomson

Jun 26 '06 #1
9 2424
Some implementation of a dirty flag, perhaps?

If (as "the Customer class" suggests) you have your own code as the
underlying class, then simply chucking a bool field onto the class and
checking / setting in each setter may suffice; you then just check IsDirty
(or whatever) to see if there are any unsaved changes, and set IsDirty to
false after saving to the DB. If you want to simplify / standardise the code
in each setter, then something like the following may help (look at what the
Name setter does):

public class Customer {
private bool _isDirty;
private string _name = "";
public bool IsDirty {
get { return _isDirty; }
private set { _isDirty = value; }
}
private bool SetValue<T>(ref T field, T value) {
if(!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
IsDirty = true;
return true;
}
return false;
}
public string Name {
get { return _name; }
set { SetValue(ref _name, value); }}
}
}

OK, the use of generics and DefaultComparer doesn't make this the quickest
runtime version, but it makes code maintenance very simple; for UI-bound
objects, I frequently extend this to:

public string Name {
get { return _name; }
set { if(SetValue(ref _name, value))
OnPropertyChanged("Name"); }}
}

where OnPropertyChanged supports the INotifyPropertyChanged interface -
again, a very simple line to put into setters to get the code right.

Marc
Jun 26 '06 #2
"thomson" <sa**********@yahoo.com> a écrit dans le message de news:
11**********************@r2g2000cwb.googlegroups.c om...

| Hi All,
| i do have a customer table in the Customer class i do have a
| function which fetches data from the table and assign to the customer
| properties,
|
| Ok, In the Front end , i get all these properties and show it to the
| web form controls.
|
| There is a save&continue button in the form, There are chances that
| none of the values will be modified , At this time i dont want the
| Modify function to be called unnececerilly,
|
| Can any one suggest how do i do it?

The normal way of doing this is to add a "Dirty" flag to the class and set
it to true in any property setters of the class.

public class MyClass
{
private bool dirty = false;

public bool Dirty
{
get { return dirty; }
}

private int someField;

public int SomeProperty
{
get { return someField; }
set
{
someField = value;
dirty = true;
}
}
}

Or you can implement INotifyPropertyChanged and capture the PropertyChanged
event :

public class MyClass : INotifyPropertyChanged
{
private PropertyChangedEventHandler propertyChanged = null;

protected virtual void OnPropertyChanged(string propertyName)
{
if (propertyChanged != null)
{
PropertyChangedEventArgs args = new
PropertyChangedEventArgs(propertyName);
propertyChanged(this, args);
}
}

event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add { propertyChanged += value; }
remove { propertyChanged -= value; }
}

private int someField;

public int SomeProperty
{
get { return someField; }
set
{
someField = value;
OnPropertyChanged("SomeProperty");
}
}
}

This then allows you to catch the event outside of the object and react to
it accordingly. This is the mechanism that data-bound UI controls use to
detect proeprty value changes.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jun 26 '06 #3
"Marc Gravell" <ma**********@gmail.com> a écrit dans le message de news:
uo*************@TK2MSFTNGP03.phx.gbl...

| Some implementation of a dirty flag, perhaps?

| I frequently extend this to:

OK, so you can read my messages before I post them can you ? :-))

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jun 26 '06 #4
Didn't you see that "antitrust"-style web-cam above your shoulder?

I did smile inwardly at the similarity of our posts; I choose to consider
this "convergence", and ratification that I'm not too /far/ from the
well-trodden path.

Aside : the code you posted may lead to false positives - but better that
than a change that slips by without notice ;-p

Marc

Jun 26 '06 #5
"Marc Gravell" <ma**********@gmail.com> a écrit dans le message de news:
%2****************@TK2MSFTNGP02.phx.gbl...

| Aside : the code you posted may lead to false positives - but better that
| than a change that slips by without notice ;-p

Heheh, I only tried to demonstrate the triggering of the flag/notification
and, yes, You are absolutely right to point out the need for an if(new not
equalto old) block to avoid such problems.

I use code similar to your generic comparison in a base business class in my
frameworks, but I found that I have a small problem comparing reference
types to their default value :

internal void SetValue<valueT>(string name, valueT value)
{
valueT oldValue = GetProperty<valueT>(name).Value;

valueT newValue = value;

IEquatable<valueT> equatableOldValue = oldValue as IEquatable<valueT>;

IEquatable<valueT> equatableNewValue = newValue as IEquatable<valueT>;
bool valueChanged = equatableNewValue.Equals(default(valueT)) ||
!equatableNewValue).Equals(oldValue);

...
}

Now the problem that occurs is when the type of valueT is a derivative of
System.Object and either oldValue or newValue are null, the test for
xxxValue.Equals(...) raises an exception; i.e. it is possible for both
newValue and oldValue to be null (default(object)).

So my question is : how do you write truly generic code like this property
setter that can test for equality against default(valueT) when
default(valueT) can be null ?

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jun 26 '06 #6
Doesn't EqualityComparer<T>.Default deal with all of these (IEquatable,
Equals, etc) usages? Looking at Roeder it seems pretty comprehensive for
typical usage...

Given the code posted, I would probably just count the nulls:

int nullCount = 0;
if(equatableOldValue==null) nullCount++;
if(equatableNewValue==null) nullCount++;
switch(nullCount) {
case 0: // no nulls, so run the actual code; doesn't matter which one
first
case 1: // one null, so can't be equal (unless you want to allow null = a
non-null object)
case 2: // two nulls, so must be equal
}

Also - A while I tried some syntax very similar to this, but recall that
enums are *not* IEquatable<themselves>, which can be a major pain. I use
lots of enums, and as we know enums are a bit weak in generics, so I
switched to EqualityComparer<T>.Default (as per my earlier post in this
chain).

Marc
Jun 26 '06 #7
"Marc Gravell" <ma**********@gmail.com> a écrit dans le message de news:
%2****************@TK2MSFTNGP04.phx.gbl...

| Doesn't EqualityComparer<T>.Default deal with all of these (IEquatable,
| Equals, etc) usages? Looking at Roeder it seems pretty comprehensive for
| typical usage...

Ah, that's interesting; yet another class I didn't know about :-) I will
investigate that further.

| Given the code posted, I would probably just count the nulls:

Of course !! Please send a few spare brain cells by return :-))

I didn't twig that any IEquatable<T> could be compared to null; sheesh !!

| Also - A while I tried some syntax very similar to this, but recall that
| enums are *not* IEquatable<themselves>, which can be a major pain. I use
| lots of enums, and as we know enums are a bit weak in generics, so I
| switched to EqualityComparer<T>.Default (as per my earlier post in this
| chain).

Yup, good point, I will definitely take allok at that. Do you find any
noticable speed penalty in this ?

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jun 26 '06 #8
Nope; it uses a lazy-loaded (on first .Default call) static field per T to
cache the appropriate comparer, so the tricky code is only run once (per T).
It isn't explicit in your code, but I'm guessing that
"GetProperty<valueT>(name).Value" uses reflection? If so, reflection is
going to be the bottlneck here, not this.

OK, stats (I got bored):

Code (follows) creates block of 1M random (seeded) ints (ValueType to
highlight any boxing issues), then tests all the data (100 times each) using
each of 3 non-inlined approaches of running it; first "x == y", second
"EqualityComparer<int>.Default.Equals(x,y)", third is like second, but
having cached EqualityComparer<int> into an IEqualityComparer<int> first.
Running everything 3 times in case of GC, JIT etc. A count is maintained to
prove that we have run the code, and not just optimised away. Running in
"release" outside of debugger on a low speed laptop. I reckon 100M tests are
performed each time, which makes sense as the results show ~100k "hits",
which tallies perfectly with a uniform distribution of 1000 values.

Direct (105400): 1031.4832
EqualityComparer (105400): 2223.1968
cached EqualityComparer (105400): 2072.9808
Direct (105400): 1031.4832
EqualityComparer (105400): 2233.2112
cached EqualityComparer (105400): 2082.9952
Direct (105400): 1021.4688
EqualityComparer (105400): 2243.2256
cached EqualityComparer (105400): 2072.9808

So - to me a factor of ~x2 (~1000ms -> ~2200ms) when going from "x==y" to
"EqualityComparer<int>.Default.Equals(x,y)" is negligable comparer to the
maintenance benefits, especially given that we are talking about property
setters here (not fractal math). The cached IEqualityComparer<int> doesn't
offer enough benefit (to my view) to be worthwhile in this usage.
The figures are largely good as the generics approach does not need boxing
or reflection.

So EqualityComparer<int>.Default.Equals(x,y) gets my vote.

Test code follows:

using System;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
static class Program {

static void Main() {
RunTest();
RunTest();
RunTest();
Console.ReadLine();
}
static void RunTest() {
const int TEST_SIZE = 1000000, LOOPS = 100;
int[] data = new int[TEST_SIZE];
Random rand = new Random(14513);
for (int i = 0; i < TEST_SIZE; i++)
data[i] = rand.Next(1000);

// force early JIT
Compare1(5, 6);
Compare2(5, 6);
Compare3(5, 6);

int matches = 0, testValue = 500;
DateTime start = DateTime.Now;
for (int loop = 0; loop < LOOPS; loop++) {
for (int i = 0; i < TEST_SIZE; i++) {
if (Compare1(data[i], testValue)) matches++;
}
}
DateTime stop = DateTime.Now;
Console.WriteLine("Direct ({0}): {1}", matches,
stop.Subtract(start).TotalMilliseconds);
matches = 0;
start = DateTime.Now;
for (int loop = 0; loop < LOOPS; loop++) {
for (int i = 0; i < TEST_SIZE; i++) {
if (Compare2(data[i], testValue)) matches++;
}
}
stop = DateTime.Now;
Console.WriteLine("EqualityComparer ({0}): {1}", matches,
stop.Subtract(start).TotalMilliseconds);
matches = 0;
start = DateTime.Now;
for (int loop = 0; loop < LOOPS; loop++) {
for (int i = 0; i < TEST_SIZE; i++) {
if (Compare3(data[i], testValue)) matches++;
}
}
stop = DateTime.Now;
Console.WriteLine("cached EqualityComparer ({0}): {1}", matches,
stop.Subtract(start).TotalMilliseconds);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Compare1(int a, int b) {
return a == b;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Compare2(int a, int b) {
return EqualityComparer<int>.Default.Equals(a,b);
}
static IEqualityComparer<int> comp = EqualityComparer<int>.Default;
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Compare3(int a, int b) {
return comp.Equals(a, b);
}
}
Jun 26 '06 #9
"Marc Gravell" <ma**********@gmail.com> a écrit dans le message de news:
Oi**************@TK2MSFTNGP05.phx.gbl...

| Nope; it uses a lazy-loaded (on first .Default call) static field per T to
| cache the appropriate comparer, so the tricky code is only run once (per
T).

Excellent, looks promising.

| It isn't explicit in your code, but I'm guessing that
| "GetProperty<valueT>(name).Value" uses reflection? If so, reflection is
| going to be the bottlneck here, not this.

Nope :-)

private Property<valueT> GetProperty<valueT>(string name)
{
return (Property<valueT>) properties[name];
}

where properties is a Dictionary<string, Property>

| So - to me a factor of ~x2 (~1000ms -> ~2200ms) when going from "x==y" to
| "EqualityComparer<int>.Default.Equals(x,y)" is negligable comparer to the
| maintenance benefits, especially given that we are talking about property
| setters here (not fractal math). The cached IEqualityComparer<int> doesn't
| offer enough benefit (to my view) to be worthwhile in this usage.
| The figures are largely good as the generics approach does not need boxing
| or reflection.

That seems perfectly acceptable; I am not doing anything intensively looping
and I think 1 second difference is not going to break the bank for that many
iterations.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jun 26 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Dave | last post by:
Hello all, When working with the STL, under what circumstances may I use a function object that modifies its internal state from one call to the next? I know this can be done with for_each<>()....
4
by: DreJoh | last post by:
I've read many articles on the subject and the majority of them give the same solution that's in article 821625 on the MSDN website. I'm using the following code and when a the client disconnects...
9
by: Greg Linwood | last post by:
I'm having difficulty understanding Session state in ASP.Net. It's almost embarrassing asking this as I've been using ASP since it was first released & it really shouldn't be this hard to use -...
3
by: William | last post by:
Hi I have an ASP.NET application that connects to an Access database. Everything works fine except for the Session object. Data in the session object is lost after I've made a call to the...
8
by: Vishwanathan Raman | last post by:
Hi I have a declared a static DataSet object SOBJ in Global.asax.I also have a localy defined DataSet LSOBJ in Global.asax which I am storing in Application State.Is there any technical...
6
by: Daniel Walzenbach | last post by:
Hi, I have a web application which sometimes throws an “out of memory†exception. To get an idea what happens I traced some values using performance monitor and got the following values (for...
3
by: Neven Klofutar | last post by:
Hi, I recently read an article on MSDN about viewstate and postback. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/viewstate.asp The author states the following:...
4
by: DreJoh | last post by:
I've read many articles on the subject and the majority of them give the same solution that's in article 821625 on the MSDN website. I'm using the following code and when a the client disconnects...
0
ADezii
by: ADezii | last post by:
In Tip #12, we showed how to display a Progress Meter within Access by using the SysCmd() Function. By using this same Function, with different Action Arguments, we will now demonstrate how you can...
4
weaknessforcats
by: weaknessforcats | last post by:
Design Patterns – State Often computer software operates based on a condition called a state. These states traditionally have been implemented using a switch statement. The cases of the switch...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.