从状态对象导航(1

这个练习的要点是在有状态的对象之间进行导航。

例如,拥有1-1和1-1的联系人应该:

  • 如果一个地址被分配给一个人,那么该人应该被分配到该地址(反之亦然)。
  • 如果地址分配给person1,然后分配给person2,那么person1将没有地址,person2将会分配。

  • 这是实现它的代码片段。

    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);
    

    现在的问题是:如何在setter中抽象代码以避免在编写大量这样的类时可能出现的错误?

    条件是:

  • A类和B类的PUBLIC接口无法更改。
  • 工厂不应该使用。
  • 不应使用静态(保持共享信息)。
  • ThreadInfo或类似的不应该使用。

  • 我真的不明白你的挑战。 当你实例化类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实例有关 。 所以即使在你实例化这个A类之前,这个B实例也必须存在。

    对于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

    你写道你不想改变AB的公共签名,并且你不想将工厂添加到代码中。 在这样的限制下,我确实看不到一致的解决方案。 或者,挑战本身不够清楚?

    编辑:在这里做一个疯狂的猜测,我认为你在这里实现的东西可以用反射来完成:你可能想要反映现有的代码(在调用堆栈中),并匹配一个新的实例,比如说, A到现有的B实例。 这可以使用反射来完成,但它非常困难,而且您必须为A s和B s的新实例之间的链接建立一组具体且强大的规则。 如果这所需解决方案的方向,那么我认为你应该深入思考并看看它是如何发展的,这是一个巨大的领域。

    链接地址: http://www.djcxy.com/p/51371.html

    上一篇: Abstracting from Stateful object navigation (1

    下一篇: Use LINQ to get items in one List<>, that are not in another List<>