I’m working on app for managing tasks. Every task has its own status. And every status has to be easily assignedable (like enum — task1.status = statuses.started). And every status has to know its displayColor, name, etc. So it cant be simple enum (I need something like — task1.status.color). I dont want to use switch, or a lot of ifs. Everithing has to be very quick (because this will be iterated a lot of times) and code has to be clean.
What I did:
public class BaseStatusType {
public Color color;
private string name;
public BaseStatusType() {
}
public override string ToString()
{
return "status" + name;
}
[Serializable]
public class Untaken : BaseStatusType
{
public Untaken()
{
color = Appname.Core.App.Default.statusUntaken;
name = "Untaken";
}
}
… and several task types(Taken, Started, Ended, Billing) more like this ..
Then there is Status class
public class Status
{
public BaseStatusType Type;
public Status()
{
this.Type = StatusType.statusUntaken;
}
}
And most important static part. Thanks to this part, it can be easily assigned.
[Serializable]
public static class StatusType {
public static BaseStatusType.Untaken statusUntaken = new BaseStatusType.Untaken();
public static BaseStatusType.Taken statusTaken = new BaseStatusType.Taken();
public static BaseStatusType.Started statusStarted = new BaseStatusType.Started();
public static BaseStatusType.Ended statusEnded = new BaseStatusType.Ended();
public static BaseStatusType.Billing statusBilling = new BaseStatusType.Billing();
}
Now, are all statuses initialized once, while app start. Not every time Status is created. While creating new Task, new Status is created, but its Type is only assigned, not created new.
Status status1 = new Status();
status1.Type = StatusType.statusEnded;
Color somecolor = status1.Type.color;
And now to the problem. Everithing work fine, until I deepClone object Task. My deepClone uses serialization/deserialization. The problem can be well described like this:
Task task1 = new Task();
task1.Status.Type = StatusType.statusEnded;
Task task2 = new Task();
task2 = task1.DeepClone();
if (task1.Status.Type == StatusType.statusEnded) {
//this returns true
}
if (task2.Status.Type == StatusType.statusEnded)
{
//this returns false
}
if (task2.Status.Type.ToString() == StatusType.statusEnded.ToString())
{
//this returns true
}
It’s probably because it creates its own StatusType.statusEnded while DeepCopy. But I dont understand why. Shouldn’t Status.Type holds only reference to a static object? I tought so. Thats why I wasn’t worry about DeepCopy. It should made only copy of reference, not copy of static object.
So what holds property Status if no address to a static value?
Your
Status.Typeproperty is not static. When you DeepClone the object a new instance is created and assigned to the cloned instance.You have two ways around this:
The advantage of #2 is that you do not have to ensure that your status objects are immutable singletons (i.e. guarantee that there is only exactly one instance and that it is never modified once created). This is a simple programming model and I doubt that it will affect performance of your application in the slightest.
The following is an example of a class implementing the IEquatable interface: