将子类传递给基类定义方法的泛型方法



问题已澄清新线程:在具有超类输入的泛型方法中访问子类属性

我有一个a级

子类B、C和D继承自A.

每个子类有3个子类a、b和c。

a、 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);}

}

如果不强制转换为派生类,就不能在派生类中定义成员并通过对基类的引用访问它:

class A {}
class B
{
public int i;
}
A a = new B();
a.i = 0; // error
((B)a).i = 0; // OK

在层次结构中的任何基类型中声明虚拟属性,或者使用转换为具体派生类型。当然,在第二种情况下,您的方法没有任何意义。

通常,您会使用在A中定义并在子类中重写的virtualabstract方法。

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...

一个优雅的解决方案是覆盖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派生的类型。

这在很大程度上取决于您真正想要实现的目标。在某些情况下,Steve Czetty的建议是最好的选择。

在其他情况下,你可以保持所有属性的不同,并在基类中有一个虚拟方法,例如,在这种情况下,它会返回一个"字符串",然后你可以在控制台中编写它或任何你想要的东西。

编辑:您可以按照Olivier的建议覆盖ToString。但只有当你感觉到你要返回的是"对象的字符串表示"时。

公共摘要A类{公共字符串PropertyA{get;set;}

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
}
}

现在,如果你需要的东西不能像这样解决,你可以扮演丹尼斯建议。

还有另一种可能性:您可以使用访问者模式。在这里你可以找到几种实现它的方法

只是为了让你有一个想法,你最终会有一个类似的课程:(这将取决于你真正想要实现的目标)您必须实现一些其他基本的东西(接口和一些方法),但从基类的引用中,您将能够轻松地调用相应的"Visit"方法。我添加的链接中有很多细节。

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

最新更新