看看这个场景:
//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
?
答案 0 :(得分: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传递给对象。
当然这会增加依赖性但有效!
答案 1 :(得分: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"
注意我已经创建了字段readonly
,这意味着以后永远不能重新分配它。这样可以确保ZField
未设置为ZZZ
foo
将返回"no"
的实例。
当然,没有什么能阻止你(或其他人)实现一个违反这些语义的单独子类:
private class Fake_ZZZ : ZZZ
{
protected override bool ImAPropertyOfAnAAADerivedClass
{
get { return true; }
}
}
new Fake_ZZZ().foo(); // "yes"
无论如何,这些语义都是笨拙和笨拙的。无论你想要用什么来完成它,都必须有更好的方法来实现它。我建议你重新考虑你的解决方案。
答案 2 :(得分: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;
}
此模式是dependency injection的一个非常简单的示例,可以为您提供所需的结果。