本练习的目的是使对象之间的导航有状态。
例如,拥有1-1关联的人员和地址应该:
这是实现它的一段代码。
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;
}
}
}
这允许以下测试通过:
// 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);
现在的问题是:如何在编写器中抽象代码以避免在编写大量此类时可能出现的错误?
条件是:
答案 0 :(得分:0)
我真的不明白你的挑战。当您实例化A类的几个实例然后实例化B类的单个实例时会发生什么?
A a1 = new A();
A a2 = new A();
A a3 = new A();
A a4 = new A();
A a5 = new A();
B b = new B();
哪个测试合格?哪一个失败了?
您会看到,实例化A
后,它会有状态。此状态应以某种方式涉及B
的实例,现有实例。因此,即使在实例化此B
类之前,此A
实例也必须存在。
B
的实例也是如此。它应该包含对已存在的A
实例的引用。
据我了解,A类应该有一个构造函数,引用现有的B实例:
public class A
{
private B b;
public A(B b)
{
this.b = b;
}
}
// Then you can have:
B b1 = new B();
A a1 = new A(b1); // here's the link
B b2 = new B();
A a2 = new A(b2); // and another link
使用B
或其他方式使用A
。
您写道,您不想更改B
和A
的公共签名,并且您不希望在代码中添加工厂。在这种限制下我真的看不到一致的解决方案。或者挑战本身还不够明确?
B
到A
的现有实例。这可以可以使用反射来完成,但这很难,你必须有一套具体而强大的规则来实现B
和{{1}} s的新实例之间的联系。 。如果 是所需解决方案的方向,那么我认为你应该深入思考并看看它是如何发展的,这是一个巨大的领域。