Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个B实例是a实例的属性吗?_C#_Oop - Fatal编程技术网

C# 这个B实例是a实例的属性吗?

C# 这个B实例是a实例的属性吗?,c#,oop,C#,Oop,看看这个场景: //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"; }

看看这个场景:

//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"
我的问题是:


是否有一种方法可以实现
imapropertyofanaaderidedclass

。你不能真的那样做。首先,类型的实例永远无法先验地知道引用它们的变量或字段是什么,因此您无法确定任何
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"
请注意,我已将字段
设置为只读
,这意味着以后再也不能重新分配它。这将确保
ZField
未设置为
ZZZ
的实例,对于该实例,
foo
将返回
“no”

当然,没有任何东西可以阻止您(或其他人)实现违反以下语义的单独子类:

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

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

无论如何,这些语义都是笨拙和笨拙的。不管你想用这个来完成什么,一定有更好的方法来完成。我建议您完全重新考虑您的解决方案。

处理需要了解
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;
 }

这个模式是一个非常简单的例子,它会给你你想要的结果。

不,它赢了;这是不可能的。因为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传递给对象


当然,这会增加依赖性,但会起作用

newzfield.foo()我很确定这里有一个错误。这是不可能的,但你为什么需要它?如果你提供你的实际问题,它可能以不同的方式解决;我需要知道(在BBB实例中)是否有任何字段被修改,但我不想在每个字段中添加事件(例如)。我在反思中发现了,但直到现在都没有办法。