473,404 Members | 2,114 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,404 software developers and data experts.

Accessor Issue

Hi guys,

maybe you can help me again in developing my bussiness project for a
company..
i make sure, that each property of an entity, mark it self dirty when
data get changed.. thats the code:
private Address address;

....

/// <summary>
/// Set or return an address object
/// </summary>

class Facility : EntityObject
{

[EntityMemberAttribute]
public Address Address
{
get { return this.address; }
set { base.MarkDirty(); this.address = value; }
}
In this case, the address object i return here, has his own members,
like: Street, Zip, City..

So, i can access them easily by: someFacility.Address.City;
the problem comes, when i try to change the city, for example:

someFacility.Address.City = "New York";
the facility class does'nt get dirty, because the someFacility.Address
property use the get accessor in order to return the address, and the
address itself use finaly the set-accessor..
is there any possibility to fix that problem, instead creating a new
address object and put that on the facility? (someFacility.Address =
new Address(... )
steven.
Nov 17 '05 #1
8 1537
Steven,

You would have to have each property on the Address class call the
MarkDirty method in order to specify that the property has changed.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Steven Wolf" <ap****@gmx.net> wrote in message
news:65**************************@posting.google.c om...
Hi guys,

maybe you can help me again in developing my bussiness project for a
company..
i make sure, that each property of an entity, mark it self dirty when
data get changed.. thats the code:
private Address address;

....

/// <summary>
/// Set or return an address object
/// </summary>

class Facility : EntityObject
{

[EntityMemberAttribute]
public Address Address
{
get { return this.address; }
set { base.MarkDirty(); this.address = value; }
}
In this case, the address object i return here, has his own members,
like: Street, Zip, City..

So, i can access them easily by: someFacility.Address.City;
the problem comes, when i try to change the city, for example:

someFacility.Address.City = "New York";
the facility class does'nt get dirty, because the someFacility.Address
property use the get accessor in order to return the address, and the
address itself use finaly the set-accessor..
is there any possibility to fix that problem, instead creating a new
address object and put that on the facility? (someFacility.Address =
new Address(... )
steven.

Nov 17 '05 #2
The first question I would have to ask is whether the Address is
intrinsically a part of Facility, or a separate thing to which Facility
refers. I'm speaking here in logical terms rather than in code terms.
Is it really true that changing the City of an Address makes the
Facility dirty and therefore needing to be written back to the
database?

Let's assume that it is true.

I would solve this problem by adding functionality to Address. I would
give it its own dirty flag and MakeDirty() method, just as you did for
Facility.

Once you have that, you have two choices as to how to handle the
aggregation problem.

The first is to change the IsDirty property of Facility to check each
of its aggregate components, like this:

public bool IsDirty
{
get
{
return this.dirty || this.address.IsDirty || this...IsDirty ||
....;
}
}

That is probably the simplest way to solve the problem: each aggregated
structure keeps its own dirty information, and aggregates such as
Facility check them whenever necessary.

However, there is also a way to keep Facility's dirty flag updated
directly. You could have Address publish a IsDirtyChanged event that
fires whenever the Address becomes dirty (or un-dirty, if you allow
that). Facility could then subscribe to that event for its Address and
update its own dirty information accordingly.

This second method is a pain in the butt, because every time the caller
says

myFacility.Address = new Address(...);

or something like that, Facility has to remember to disconnect its
event handler from the Address that it has at the moment, assign the
new Address, and then connects its event handler to the new Address.

I like the first method better, myself. It's simpler and easier to
maintain.

Nov 17 '05 #3
hi nicholas,

the address class is independent, so in my case, i have to tell the
parent class to mark itself as dirty on changing in the address class.

steven.


"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:<#v**************@TK2MSFTNGP12.phx.gbl>...
Steven,

You would have to have each property on the Address class call the
MarkDirty method in order to specify that the property has changed.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Steven Wolf" <ap****@gmx.net> wrote in message
news:65**************************@posting.google.c om...
Hi guys,

maybe you can help me again in developing my bussiness project for a
company..
i make sure, that each property of an entity, mark it self dirty when
data get changed.. thats the code:
private Address address;

....

/// <summary>
/// Set or return an address object
/// </summary>

class Facility : EntityObject
{

[EntityMemberAttribute]
public Address Address
{
get { return this.address; }
set { base.MarkDirty(); this.address = value; }
}
In this case, the address object i return here, has his own members,
like: Street, Zip, City..

So, i can access them easily by: someFacility.Address.City;
the problem comes, when i try to change the city, for example:

someFacility.Address.City = "New York";
the facility class does'nt get dirty, because the someFacility.Address
property use the get accessor in order to return the address, and the
address itself use finaly the set-accessor..
is there any possibility to fix that problem, instead creating a new
address object and put that on the facility? (someFacility.Address =
new Address(... )
steven.

Nov 17 '05 #4
hi bruce,

The first question I would have to ask is whether the Address is
intrinsically a part of Facility, or a separate thing to which Facility
refers. I'm speaking here in logical terms rather than in code terms.
the address class is independent/seperated, and can be use in other
classes.. an user could have an address too ( but i dont provide that
now, since a user is hooked to a facility), so i would use the same
address class as the facility do.

Is it really true that changing the City of an Address makes the
Facility dirty and therefore needing to be written back to the
database?

yes thats true.
Let's assume that it is true.

I would solve this problem by adding functionality to Address. I would
give it its own dirty flag and MakeDirty() method, just as you did for
Facility.

yes i do that already.

Once you have that, you have two choices as to how to handle the
aggregation problem.

The first is to change the IsDirty property of Facility to check each
of its aggregate components, like this:

public bool IsDirty
{
get
{
return this.dirty || this.address.IsDirty || this...IsDirty ||
...;
}
}

well, i cant to that, because the facility is derived from a base
class, and the base class carry all those isDirty, isNew... flags and
some other important things..

see my code before... ( ..base.MarkDirty(); )
However, there is also a way to keep Facility's dirty flag updated
directly. You could have Address publish a IsDirtyChanged event that
fires whenever the Address becomes dirty (or un-dirty, if you allow
that). Facility could then subscribe to that event for its Address and
update its own dirty information accordingly.

well, that sounds good..
but i have an entity, called contact. i store there all user
informations and i have there 4 similar objects:

public class Contact : EntityObject, ILazyLoading
{

...
private PhoneNumber phone;
private PhoneNumber fax;
private PhoneNumber mobile;
private EMail eMail;
...
the PhoneNumber class, store the internation area code, area code, and
the call number. i like to go this way instead store the numbers as
strings. the same thing for the email, to provide some basic
email-address validations. all those classes provide properties and
mark them self as dirty too, but again i have to mark, in this case,
the contact class as dirty, when for example the area code of the
PhoneNumber class get changed.

so, in my case, each entity (facility, contact..) would subscribe to
my "custom types" events?
This second method is a pain in the butt, because every time the caller
says

myFacility.Address = new Address(...);

or something like that, Facility has to remember to disconnect its
event handler from the Address that it has at the moment, assign the
new Address, and then connects its event handler to the new Address.


oh yes, i also try to keep my entites as simple as possible, but thats
a mass a little..

anyway, thank you for your support.
Nov 17 '05 #5
>> The first is to change the IsDirty property of Facility to check
each
of its aggregate components, like this: public bool IsDirty
{
get
{
return this.dirty || this.address.IsDirty || this...IsDirty || ...;
}
}
well, i cant to that, because the facility is derived from a base
class, and the base class carry all those isDirty, isNew... flags and some other important things.. see my code before... ( ..base.MarkDirty(); )


Yes, you still can. You should do it like this:

public class BaseClass
{
private bool _isDirty = false;

...
public void MakeDirty()
{
this._isDirty = true;
}

public virtual bool IsDirty
{
get { return this._isDirty; }
}
}

public class Facility : BaseClass
{
private Address _facilityAddress;
...
public override bool IsDirty
{
get { return base.IsDirty || this._facilityAddress.IsDirty ||
.... ; }
}
}

You should have an IsDirty property anyway... nobody should be looking
at the local isDirty flag in the base class. That should be private.
So, all you do is declare the property virtual and then override it in
classes that have complex fields like Addresses and PhoneNumbers.

I think that this is much cleaner and easier than messing with events,
etc.

Nov 17 '05 #6
You should (almost) always make fields private. You should (almost)
always expose fields to inheriting classes and to the outside world via
properties. This allows you to do things like what I did in the code
example: make a property do more than just return a field value.

In my code example, the "_isDirty" flag tells you only if the fields
directly stored by Facility have been changed. "_isDirty" _doesn't_
tell you whether anything inside Address has been changed. That's why
the IsDirty property (which is different from the "_isDirty" flag) does
extra work: it knows that it has to check _isDirty _plus_ the IsDirty
properties of any composite objects that are part of Facility.

Your session objects should look to the IsDirty property (not the
field) to see whether to write the entity back to the database. (They
won't be able to look at the field anyway, because it's now private.)

Yours is a classic example of why it's better to never to expose
fields, and expose properties instead: what you thought, in your
original design, was a simple boolean flag test (just test the _isDirty
flag) turned out to be more complicated. If you expose properties you
can always add more code to the get accessor. You can also override
properties in child classes and make them more sophisticated than in
the base class. You can't do any of that with fields.

DateTime is a struct, not a class. It uses value semantics. So, if you
have a DateTime in your Facility:

public class Facility : BaseClass
{
private DateTime _whenBuilt;
...
public DateTime WhenBuilt
{
get { return this._whenBuilt; }
set { this._whenBuilt = value; MakeDirty(); }
}
}

....you cannot, in fact, do this:

myFacility.WhenBuilt.AddDays(10);

If you look back at myFacility, you'll see that nothing has happened to
the date! You need to read up on value versus reference types to really
understand why, but the quick answer is that the DateTime is copied
onto the stack to return it from the WhenBuilt property, so the
AddDays() method adds 10 days to a temporary copy, not the version you
store inside your Facility class.

So, if you have fields that are structs, then they are safe.

If, however, you have a field that is a reference to a class that
someone else created and you can't modify, then you are correct: you
have two choices.

1. Subclass the class and add the "dirty" logic in the subclass.
Personally, I think that this is ugly.

2. Change the property that gets / sets this object to store a copy of
it:

public OtherClass OtherProperty
{
get { return this._other; }
set { this._other = value; this._otherCopy = value.Clone();
MakeDirty(); }
}

now you can change your IsDirty property to compare the two items to
see if they're still the same:

public bool IsDirty
{
get
{
bool dirty = this._isDirty || this._address.IsDirty ||
!this._other.Equals(this._otherCopy);
}
}

Since your caller can only get the original object (and use its methods
/ properties to modify it) and not the copy, you can detect any
changes.

This assumes, of course, that the class OtherClass implements Equals()
and is ICloneable. If it isn't then you'll have to do the "Equals"
comparison yourself in open code, and clone the object by constructing
a new one and setting its properties appropriately.

Nov 17 '05 #7
It sounds to me as though you understand everything I was saying. I'm
glad that I could be of help.

I have a homepage? Perhaps you're confusing me with Jon Skeet? :)

Nov 17 '05 #8

"Bruce Wood" wrote:
It sounds to me as though you understand everything I was saying. I'm
glad that I could be of help.

I have a homepage? Perhaps you're confusing me with Jon Skeet? :)


i glad that you could help me too! thank you a lot.
yes, i mixed you up with jon skeet ;)
Nov 17 '05 #9

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

Similar topics

22
by: mirandacascade | last post by:
When I look at how classes are set up in other languages (e.g. C++), I often observe the following patterns: 1) for each data member, the class will have an accessor member function (a...
3
by: LuCk | last post by:
Can someone explain what these really are for example: ---------------------------------------------------------- void SetFrameRate(int iFrameRate) { m_iFrameDelay = 1000 / iFrameRate; }; ...
10
by: ma740988 | last post by:
I'm hoping my post here doesn't fall into the 'hard to say' category, nonetheless I've been advised that multiple uses of accessor/mutator (get/set) member functions can be viewed as a 'design...
1
by: Pol Bawin | last post by:
Hi, I have a objectA with a property that return an object B (accessor GET only) I have defined an ExpandableObjectConverter on the type B and overrided CanConvertTo, CanConvertFrom, ... The...
6
by: Jason Shohet | last post by:
I have a class with protected variables and some accessor methods, , get, set ... Maybe I have a brain blockage today but I'm thinking, why not just make those variables public. After all,...
11
by: Kavvy | last post by:
How come a lot of the examples I have seen on the net define accessor pairs within a class, and then only ever use the accessor outside the class? When used within the class the variable is...
0
by: Steven Wolf | last post by:
Hi guys, maybe you can help me again in developing my bussiness project for a company.. i make sure, that each property of an entity, mark it self dirty when data get changed.. thats the...
7
by: Javaman59 | last post by:
This is probably common knowledge to .Net gurus, but please bear with me while I share a discovery with the group... I needed to create a public lock on a class, as follows... class Locked {...
5
by: Stacey Levine | last post by:
I have a webservice that I wanted to return an ArrayList..Well the service compiles and runs when I have the output defined as ArrayList, but the WSDL defines the output as an Object so I was...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.