1

问题已澄清新线程:在通用方法中使用超类输入访问子类属性

我有一个基类 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

4 回答 4

1

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

class A {}
class B
{
    public int i;
}

A a = new B();
a.i = 0; // error
((B)a).i = 0; // OK

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

于 2013-09-20T17:12:33.423 回答
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.

于 2013-09-20T17:20:41.923 回答
0

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

在其他情况下,您可以只保持所有属性不同,并在基类中有一个虚拟方法,例如在这种情况下返回一个“字符串”,然后您可以在控制台或任何您希望的内容中编写它。

编辑:您可以按照 Olivier 的建议覆盖ToString 。但只有当你觉得你要重新调整的是“对象的字符串表示”时。

公共抽象类 A { 公共字符串 PropertyA { 获取;放; }

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

现在,如果您需要的东西不能像这样解决,您可以按 Dennis Suggested 进行投射。

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

就这样你有一个想法,你最终会拥有一个类似于这样的类:(这将取决于你真正想要实现的目标)你必须实现一些其他基本的东西(接口和一些方法),但是从对基类,您将能够轻松调用相应的“访问”方法。我添加的链接中有很多细节。

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); }
    }
于 2013-09-20T17:23:27.673 回答
0

通常,您将使用在子类中定义和覆盖的virtualorabstract方法。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...
于 2013-09-20T17:07:57.393 回答