Шаблонные классы и функции

251
23 февраля 2017, 23:16

Предположим, имеется следующая структура классов:

public abstract class AbstractClass<T> where T : ISomeInterface
{
    public abstract T AbstractMethod();
}
public class Child : AbstractClass<ISomeInterfaceImplementation> 
{
    public override ISomeInterfaceImplementation AbstractMethod() { }
}
public class ChildTwo : AbstractClass<ISomeInterfaceImplementationTwo> 
{
    public override ISomeInterfaceImplementationTwo AbstractMethod() { }
}
public class SomeClass
{
    private readonly SomeType _someType;
    public ISomeInterfaceImplementation SomeMethod()
    {
        return new Child(_someType).AbstractMethod();
    }
    public ISomeInterfaceImplementationTwo SomeMethodTwo()
    {
        return new ChildTwo(_someType).AbstractMethod();
    }
}

В классе SomeClass отчётливо видно повторение кода, и хотелось бы написать что-то похожее на это:

public ISomeInterface SomeMethod<TAbstractClassChild>()
    where TAbstractClassChild : AbstractClass<ISomeInterface>
{
    return (TAbstractClassChild)Activator.CreateInstance(typeof(TAbstractChild), _someType).AbstractMethod();
}

Для того, чтобы потом можно было просто написать new SomeClass().SomeMethod<Child>(); и new SomeClass().SomeMethod<ChildTwo>(); и так далее, вместо

var someClass = new SomeClass();
var sm = someClass.SomeMethod();
var smTwo = someClass.SomeMethodTwo();

Понимаю, что я где-то близко, но не получается, запутался. Подскажите, как исправить код, либо структуру классов, чтобы можно было это получить.

Answer 1

Если я правильно понял вопрос, то например так:

public class SomeClass
{
    public ISomeInterface SomeMethod<T, C>()
            where C : ISomeInterface
            where T : AbstractClass<C>, new()
    {
        return new T().AbstractMethod();
    }
}
Answer 2

Наверное, стоит посмотреть на проблему этого кода с той стороны, что вы используете явно статичный метод (AbstractMethod) в динамическом контексте. Вы создаете ненужные объекты (new Child(...), new ChildTwo(...)) единственный смысл которых, быть удаленным сборщиком мусора. (так же, открытый вопрос о целесообразности передачи аргумента SomeType через конструктор)

Думаю, что в вашем случае, уместней было бы обойтись абстрактной фабрикой, вместо иерархии:

public interface ISomeFactory {
    ISomeInterface CreateImplOne();    
    ISomeInterface CreateImplTwo();
}
READ ALSO
Собрать почту по POP3 и передать по SMTP

Собрать почту по POP3 и передать по SMTP

Необходимо организовать сбор почты со стороннего сервера по POP3, обработать письма и по SMTP отправить на наш сервер microsoft exchangeДак вот, как собрать...

278
Как хранить сюжетную линию игры?

Как хранить сюжетную линию игры?

Как хранить сюжетную линию, если она представляет вот такое дерево:

305
checkbox list в yii

checkbox list в yii

ЗдравствуйтеПрошел много форумов и статей, всё равно ничего не получается

489
Как реализовать свой API?

Как реализовать свой API?

Нужно реализовать API, которым будут пользоваться с другого сайта (те

756