-2

看看这个场景:

//base class
abstract class AAA { } 

//class 1
class BBB : AAA
{
     //Field of ZZZ type
     public ZZZ ZField = new ZZZ();
}

//class 2
class ZZZ
{
      public string foo() { return ImAPropertyOfAnAAADerivedClass ? "yes" : "no"; }

      bool ImAPropertyOfAnAAADerivedClass 
      {
          get { /* here */ }
      }
}

//running test
new BBB().ZField.foo(); // => expected "yes"
new ZField.foo(); // => expected "no"

我的问题是:

有没有办法实现ImAPropertyOfAnAAADerivedClass

4

3 回答 3

2

不,这是不可能的。由于 ZZZ 与 AAA 没有直接关系。一种可能的方法是从 ZZZ 公开一个公共对象并将 BBB ref 传递给它,然后检查它:

public class ZZZ
{
  public string foo() { return ImAPropertyOfAnAAADerivedClass ? "yes" : "no"; }

  bool ImAPropertyOfAnAAADerivedClass 
  {
      get { return TestForAAA is AAA; }
  }

  public object TestForAAA { get; set; }
}

并且在使用它时会将 BBB 的 ref 传递给对象。

当然,这会增加依赖性但有效!

于 2013-07-18T03:09:35.237 回答
1

没有。你真的不能那样做。首先,类型的实例永远无法先验地知道哪些变量或字段正在引用它们,因此您无法确定任何BBB.ZField指向当前ZZZ实例。

你能得到的最接近的是这样的:

public class ZZZ
{
    public string foo() { return ImAPropertyOfAnAAADerivedClass ? "yes" : "no"; }
    protected bool virtual ImAPropertyOfAnAAADerivedClass 
    {
        get { return false; }
    }
}

class BBB : AAA
{
    //Field of ZZZ type
    public readonly ZZZ ZField = new BBB_ZZZ();

    private class BBB_ZZZ : ZZZ
    {
        protected override bool ImAPropertyOfAnAAADerivedClass 
        {
            get { return true; }
        }
    }
}


new BBB().ZField.foo(); // "yes"
new ZZZ().foo();        // "no"

请注意,我已经创建了 field readonly,这意味着以后永远不能重新分配它。这将确保ZField未将其设置ZZZfoo将返回的实例"no"

当然,没有什么能阻止你(或其他人)实现一个违反这些语义的单独子类:

private class Fake_ZZZ : ZZZ
{
    protected override bool ImAPropertyOfAnAAADerivedClass 
    {
        get { return true; }
    }
}

new Fake_ZZZ().foo();   // "yes"

无论如何,这些语义是笨拙和尴尬的。无论你想用它来完成什么,都必须有更好的方法来实现它。我建议您完全重新考虑您的解决方案。

于 2013-07-18T02:47:19.470 回答
1

处理需要知道ZZZ实例容器的最佳方法是将其注入到ZZZ.

 public class ZZZ
 { 
     public ZZZ(object owner = null)
     { 
       this.owner = owner;
     }
     readonly object owner;

     public bool ImAPropertyOfAnAAADerivedClass 
     {
         get { return owner is AAA; }
     }
 }

然后,要使其与您的包含类一起工作,请将BBB定义更改为:

 public class BBB : AAA
 {
     public BBB(){ 
        ZField = new ZZZ(this);
     }
     public readonly ZZZ ZField;
 }

此模式是一个非常简单的依赖注入示例,它将为您提供所需的结果。

于 2013-07-18T03:07:40.777 回答