通用方法将subClass传递给baseClass定义的方法?

时间:2013-09-20 16:55:23

标签: c# generics

问题是澄清的 新主题: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);}


}

4 个答案:

答案 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中定义的abstractA方法,并在子类中重写。

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