Hi,
The point of this exercise is to make navigation between objects stateful.
For example, having Person and Address with 1-1 association it should:
- If an address is assigned to a persons, then the person should be assigned to the address (and vice versa).
- If address is assigned to person1 and then to person2, then the person1 will have no address and person2 will.
This is the piece of code that implements it.
public class A {
internal B a;
public B Value {
get {
return a;
}
set {
if (value == null) {
if (a != null)
a.a = null;
} else
value.a = this;
a = value;
}
}
}
public class B {
internal A a;
public A Value {
get {
return a;
}
set {
if (value == null) {
if (a != null)
a.a = null;
} else
value.a = this;
a = value;
}
}
}
This allows following tests to pass:
// For the common setup:
var a = new A();
var b = new B();
// Test 1:
a.Value = b;
Assert.AreSame(a, b.Value);
// Test 2:
b.Value = a;
Assert.AreEqual(b, a.Value);
// Test 3:
b.Value = a;
b.Value = null;
Assert.IsNull(a.Value);
// Test 4:
var a2 = new A();
b.Value = a2;
Assert.AreSame(b, a2.Value);
Assert.AreNotSame(a, b.Value);
// Test 5:
a.Value = b;
Assert.AreSame(a, b.Value);
var a1 = new A();
var b1 = new B();
a1.Value = b1;
Assert.AreSame(a1, b1.Value);
// Test 6:
var a1 = new A();
var b1 = new B();
Assert.IsNull(a.Value);
Assert.IsNull(b.Value);
Assert.IsNull(a1.Value);
Assert.IsNull(b1.Value);
Now the question is: how would you abstract the code in the setters to avoid possible mistakes when writing a lot of such classes?
The conditions are:
- The PUBLIC interfaces of classes A and B cannot be changed.
- Factories should not be used.
- Statics should not be used (to persist shared info).
- ThreadInfo or similar should not be used.