Создание правильного универсального класса по параметру типа в C # - PullRequest
0 голосов
/ 03 июля 2018

У меня есть этот код для выполнения операций над объектами базового класса:

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Base>() { new A(), new B() };
        var v = new Visitor();
        list.ForEach(e => e.Accept(v));
    }
}

public abstract class Base
{
    public abstract void Accept(Visitor visitor);
}

public class A : Base
{
    public override void Accept(Visitor visitor) => visitor.Visit(this);
}

public class B : Base
{
    public override void Accept(Visitor visitor) => visitor.Visit(this);
}

public class Visitor
{
    Writer writer = new Writer();
    public void Visit(A a) => writer.Write(a);
    public void Visit(B b) => writer.Write(b);
}

public class Writer
{
    public void Write(A a) => Console.WriteLine("A");
    public void Write(B b) => Console.WriteLine("B");
}

Я хочу разделить Writer на отдельные классы, потому что будет много других объектов со сложной иерархией. Это может быть:

public interface Writer<T> where T : Base
{
    void Write(T t);
}

public class WriterA : Writer<A>
{
    public void Write(A t) => Console.WriteLine("A");
}

public class WriterB : Writer<B>
{
    public void Write(B t) => Console.WriteLine("B");
}

но я не знаю, как создавать собственные классы по заданному параметру типа, а не вызывать их явно. Спасибо.

1 Ответ

0 голосов
/ 03 июля 2018

Вам нужно будет написать WriterFactory:

class WriterFactory{
    Dictionary<string, Func<object>> _creators = { 
            { "A", ()=> new WriterA() },
            { "B", ()=> new WriterB() } 
       };

    public Writer<T> Create<T>(){
         return (Writer<T>)_creators[typeof(T).Name]();
    }

Чем вы можете использовать его в Visitor:

public class Visitor
{
    Writer writerFactory = new WriterFactory();
    public void Visit(A a) => writerFactory.Create<A>().Write(a);
    public void Visit(B b) => writerFactory.Create<B>().Write(b);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...