Mutually exclusive property across instances?
-
So I have this class, Apple. There can be many instances of Apple, but only one can be my favorite at any given time. So the question is how best to manage a mutually exclusive property on a collection of objects? Here’s a potential solution but I don’t know if it’s bad form or not (the meat is in the property-set and uses the static FavoriteApple field).
public class Apple { private static Apple FavoriteApple; private bool isFavorite; public bool IsFavorite { get { return this.isFavorite; } set { // Set this instance's isFavorite field. this.isFavorite = value; if (value == true) { // Set the current favorite apple's IsFavorite property to false. Apple.FavoriteApple.IsFavorite = false; // Set the static "FavoriteApple" reference to this instance. Apple.FavoriteApple = this; } else { // If the static "FavoriteApple" reference is pointing to this instance, null it out. if (this == Apple.FavoriteApple) Apple.FavoriteApple = null; } } } }
The question is about the proper use of properties. Is it reasonable to set a property on an instance of a class and have it affect the state of another instance? Intuitively this seems wrong. But how else can you handle the setting of an object property that is by design mutually exclusive amongst all instances of the class? The most obvious alternative is to leave it to the programmer to somehow enforce the mutual exclusivity. This puts the burden on the programmer and opens up the potential for some serious bugs, but doesn’t do any fishy stuff behind the scenes. Everything is explicit. Another solution is to remove the "IsFavorite" property from the Apple class all together and us a reference external to the Apple class to keep track of the "favorite" apple. The only problem with this is that if Apple instances are treated differently based on whether or not they are the "Favorite", then the reference to the "Favorite" apple has to be passed around with the Apple instances. At any rate, the method I've illustrated here works, the only question is does it violate a best practice or coding principle by changing the state of one instance implicitly when changing the state of another instance explicitly. Thoughts? -
So I have this class, Apple. There can be many instances of Apple, but only one can be my favorite at any given time. So the question is how best to manage a mutually exclusive property on a collection of objects? Here’s a potential solution but I don’t know if it’s bad form or not (the meat is in the property-set and uses the static FavoriteApple field).
public class Apple { private static Apple FavoriteApple; private bool isFavorite; public bool IsFavorite { get { return this.isFavorite; } set { // Set this instance's isFavorite field. this.isFavorite = value; if (value == true) { // Set the current favorite apple's IsFavorite property to false. Apple.FavoriteApple.IsFavorite = false; // Set the static "FavoriteApple" reference to this instance. Apple.FavoriteApple = this; } else { // If the static "FavoriteApple" reference is pointing to this instance, null it out. if (this == Apple.FavoriteApple) Apple.FavoriteApple = null; } } } }
The question is about the proper use of properties. Is it reasonable to set a property on an instance of a class and have it affect the state of another instance? Intuitively this seems wrong. But how else can you handle the setting of an object property that is by design mutually exclusive amongst all instances of the class? The most obvious alternative is to leave it to the programmer to somehow enforce the mutual exclusivity. This puts the burden on the programmer and opens up the potential for some serious bugs, but doesn’t do any fishy stuff behind the scenes. Everything is explicit. Another solution is to remove the "IsFavorite" property from the Apple class all together and us a reference external to the Apple class to keep track of the "favorite" apple. The only problem with this is that if Apple instances are treated differently based on whether or not they are the "Favorite", then the reference to the "Favorite" apple has to be passed around with the Apple instances. At any rate, the method I've illustrated here works, the only question is does it violate a best practice or coding principle by changing the state of one instance implicitly when changing the state of another instance explicitly. Thoughts?Why do you need an isFavourite member? Just have your static Apple favourite member, and an IsFavourite property get { return this == favourite; } Then you can set the favourite apple to the instance that is your favourite. The code reflects the real world problem domain, which indicates its a good design.
Mark Churchill Director Dunn & Churchill Diamond Binding: Zero to Data Layer in 3 mins
-
Why do you need an isFavourite member? Just have your static Apple favourite member, and an IsFavourite property get { return this == favourite; } Then you can set the favourite apple to the instance that is your favourite. The code reflects the real world problem domain, which indicates its a good design.
Mark Churchill Director Dunn & Churchill Diamond Binding: Zero to Data Layer in 3 mins
The reason for the member is that the state must be remembered across sessions and you can't serialize a static member. But your point is well taken. I may be approaching this the wrong way. Perhaps having the "IsFavorite" as a property of the class, there should simply be a separate Apple reference that is updated to refer to the current favorite apple. Thanks for your response!
-
The reason for the member is that the state must be remembered across sessions and you can't serialize a static member. But your point is well taken. I may be approaching this the wrong way. Perhaps having the "IsFavorite" as a property of the class, there should simply be a separate Apple reference that is updated to refer to the current favorite apple. Thanks for your response!
In that case your database will need a Person type to represent you, and a Person.FavouriteApple member ;)
Mark Churchill Director Dunn & Churchill Diamond Binding: Zero to Data Layer in 3 mins