问题是澄清的 新主题:subclass properties accessed in generic method with superclass input
我有一个基类A
子类B,C和D继承自A。
每个子类有3个子类a,b和c。
a,b和c有一个独特属性列表。
但是,现在我想构建一个通用函数来访问这些属性,那么如何在不打开Type的情况下执行此操作?
澄清:我不希望a:B有抽象的C方法/属性
示例:
public void Method(A a){
if(a.isSubClassOf(B))
{Console.WriteLine(a.BaProperty);}
if(a.isSubClassOf(C))
{Console.WriteLine(a.CbProperty);}
if(a.isSubClassOf(D))
{Console.WriteLine(a.DcProperty);}
}
答案 0 :(得分:1)
您无法在派生类中定义成员并通过对基类的引用来访问它,而无需转换为派生类:
class A {}
class B
{
public int i;
}
A a = new B();
a.i = 0; // error
((B)a).i = 0; // OK
在层次结构中的任何基类型中声明虚拟属性,或使用强制转换为具体的派生类型。当然,在第二种情况下,你的方法没有任何意义。
答案 1 :(得分:0)
通常,您可以使用virtual
中定义的abstract
或A
方法,并在子类中重写。
public abstract class A
{
protected abstract PropertyType PropertyValue {get;}
public void Method()
{
Console.WriteLine(PropertyValue);
}
}
public class B : A
{
protected override PropertyType Property { get { return PropertyType.B; } }
}
// etc...
答案 2 :(得分:0)
优雅的解决方案是覆盖ToString
public abstract class A { }
public class B : A {
public int b { get; set; }
public override string ToString()
{
return b.ToString();
}
}
// Do the same with C and D ....
A[] array = new A[] { new B(), new C(), new D() };
foreach (A a in array) {
Console.WriteLine(a);
}
请注意,Console.WriteLine
无需了解A
中的特殊方法或属性。它也适用于不是A
。
答案 3 :(得分:0)
这在很大程度上取决于你真正想要实现的目标。在某些情况下,Steve Czetty建议的是最好的选择。
在其他情况下,您可以保持所有属性不同,并在基类中有一个虚方法,例如在这种情况下返回一个“字符串”,然后您可以在控制台或任何您想要的内容中写入。
修改:您可以像Olivier建议的那样覆盖ToString。但只有当你觉得你要重新调整的是“对象的字符串表示”时。
公共抽象类A. { public string PropertyA {get;组; }
public virtual string GetString() //
{
return PropertyA;
}
}
public class B:A
{
public string PropertyB { get; set; }
public override string GetString()
{
return PropertyB;
}
}
public class C:A
{
public string PropertyC { get; set; }
public override string GetString()
{
return string.Format("{0} - {1}", base.GetString(), PropertyC) // for example if you wanted to do something more complex
}
}
现在,如果你需要的东西不能像这样解决,你可以扮演丹尼斯建议。
还有另一种可能性:你可以使用访客模式。 Here您可以找到几种方法来实现它。
这样你就有了一个想法,你最终会得到一个类似于此的类:(这将取决于你真正想要实现的目标) 您必须实现一些其他基本的东西(接口和一些方法),但是从引用到基类,您将能够轻松地调用相应的“访问”方法。我添加的链接中有很多细节。
class ClassicVisitor : IAVisitor
{
public string SuperComplexStringResult { get;set; }
public void Visit(B b) { SuperComplexStringResult = String.Format("Super Complex Stuff + {0}", b.PropertyB); }
public void Visit(C c) { SuperComplexStringResult = String.Format("Super Complex Stuff + {0}", c.PropertyC); }
}