避免向下投射/反射的模式

时间:2019-04-08 15:28:22

标签: c# reflection abstraction downcast

假设我有两个基类的实现:

public class Base { 
    public string Stringify() { return "I am a member of base class"; }
}

public class A : Base {
    public void DoAThing() {...};
}

public class B : Base {
    public void DoBThing(int anInteger) {...};
}

假设我想在列表中放置Base的许多实例,以便我可以遍历它们并在每个实例上调用Stringify(),并利用它们的共享功能。

static void Main(string[] args)
{
    A thing1 = new A();
    B thing2 = new B();
    B thing3 = new B();     
    List<Base> list = new List<Base> {thing1, thing2, thing3};
    foreach(Base base in list) { Console.WriteLine(base.Stringify()); }           
}

现在假设有许多Base对象,因此维持对每个引用的单独thing引用是不现实的。是否有任何方法可以仅通过列表重新获得抽象所丢失的DoAThing()DoBThing()功能,而不必使用显式的向下转换和反射?

感觉这将是足够普遍的情况,所以我想知道我是否缺少设计缺陷或既定模式,在这种情况下会有所帮助。

1 个答案:

答案 0 :(得分:0)

如果进行调试,您会注意到列表中的每个对象都包含其类。

这种方式:

class Program
{
    static void Main(string[] args)
    {
        A thing1 = new A();
        B thing2 = new B();
        B thing3 = new B();
        List<Base> list = new List<Base> { thing1, thing2, thing3 };
        foreach (Base bas in list) {
            Console.WriteLine(bas.Stringify());

            if(bas is A)
            {
                ((A)bas).DoAThing();
            }
            else if (bas is B)
            {
                ((B)bas).DoBThing(1);
            }
            else
            {
                //IDK
            }
        }
    }

}

public abstract class Base
{
    public string Stringify() { return "I am a member of base class"; }
}

public class A : Base
{
    public void DoAThing()
    {

    }
}

public class B : Base
{
    public void DoBThing(int anInteger)
    {

    }
}