Шаблон, чтобы избежать необходимости Даункинг / Отражение - PullRequest
0 голосов
/ 08 апреля 2019

Предположим, у меня есть две реализации базового класса:

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 голосов
/ 08 апреля 2019

Если вы отлаживаете, вы можете заметить, что каждый объект списка содержит свой класс.

Таким образом:

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)
    {

    }
}
...