2015-09-24 8 views
0

Я работаю над старым фрагментом кода и пытается его реализовать заново с новыми достижениями в .NET. Однако я не могу обернуть голову вокруг дизайна тем же. Раньше не было классов шаблонов/интерфейсов, и теперь мне нужно использовать их. Я попытаюсь привести пример дизайна и где я застрял. Дизайн выглядит примерно так:Дизайн классов с общим классом и интерфейсом в C#

interface Service<T> 
{ 
    T Value; 
    Task AsyncWork(); 
} 

class Input<T> : Service<T>, Input 
{ 
    Worker w1; 
    Task AsyncWork() 
    { 
     w1.WorkOnInput(this); //error 
     ... //will return a Task eventually 
    } 

} 

class Input 
{ 
    //common members and methods for child classes 
    int priority; 
    string Name; 
    FormatInput() 
    { 
     //some common implementation 
    } 

} 

class StringInput:Input<string> 
{ 
    //Implementation specific to string input 
} 

class IntInput:Input<int> 
{ 
    //Implementation specific to int input 
} 

class Worker 
{ 
    WorkOnInput(Input) 
    { 
     ... 
    } 
} 

Main() 
{ 
    Worker w = new Worker(); 
    Input input1 = new StringInput(); 
    Input input2 = new IntInput(); 
    input1.FormatInput(); 
    input2.FormatInput(); 
    List<Input> inputList = new List<Input>(); 
    inputList.Add(input1); 
    inputList.Add(input2); 
    AnotherMethod(inputList); //another method which expects a list of Inputs 
    w.WorkOnInput(input1); 
    w.WorkOnInput(input2); 
} 

Я не могу изменить реализацию интерфейса, поскольку я не являюсь его владельцем. Но, как показывает комментарий, я бы ошибся на w1.WorkOnInput(this), так как здесь здесь Input, а не Input<T>.

Однако если изменить WorkOnInput принять аргумент типа Input<T>, то я должен был бы сделать это универсальный метод, как WorkOnInput<T> и если я должен был бы назвать это я бы явно должен обеспечить тип входа, который также нежелательно.

Также у меня есть список входов, которые необходимо передать AnotherMethod(), а List<Input<T>> невозможен.

Я думаю, что я немного запутался со сценарием и обойдусь без какого-либо конкретного решения.

Может ли кто-нибудь указать мне направление вправо?

+2

Не следует 'class Ввод : Service , Input' be' class Ввод : Вход, Сервис '? ... и если вы можете, вы должны переименовать 'Service ' как 'IService ' –

+0

Вы пробовали 'w1.WorkOnInput ((Input) this);'? – tomab

+0

Итак, сделайте 'public class TList : List > {}' –

ответ

2

Не должно быть class Input<T> : Service<T>, Input be class Input<T> : Input, Service<T>?

... и если вы можете, вы должны переименовать Service<T> как IService<T> - Это интерфейс, а не класс. Следуя лучшие конвенции практики присвоения имен, было бы писать

class Input<T> : IService<T>, Input 

ясно и очевидно, неправильно, вызывает зависимость интерфейса перечислена до одного и разрешено только базового класса.