2013-08-21 3 views
2

Скажем, у меня есть следующий интерфейсОбщий интерфейс, реализующий несколько общих типов - как разделить реализацию метода?

public interface IFilter<T> 
{ 
    IEnumerable<T> ApplyFilter(IEnumerable<T> list); 
} 

и конкретной реализации, как это:

public class PetFilter: IFilter<Dog>, IFilter<Cat> 
{ 
    public IEnumerable<Dog> ApplyFilter(IEnumerable<Dog> list) 
    { 
     return ApplyFilter<Dog>(list); 
    } 

    public IEnumerable<Cat> ApplyFilter(IEnumerable<Cat> list) 
    { 
     return ApplyFilter<Cat>(list); 
    } 

    private IEnumerable<T> ApplyFilter<T>(IEnumerable<T> list) 
    { 
     // do the work here 
    } 
} 

Есть ли способ, чтобы избежать необходимости осуществлять отдельные методы как собаки и кошки, при условии, что они использовать одну и ту же реализацию?

+2

Do Cat and Dog оба наследуют от общего основания, которое определяет все значения, которые вы хотите фильтровать? –

+0

Не очень хорошая идея. Очень показательно, как вы сразу создали ошибку в этом фрагменте. –

ответ

2

Да и нет. Когда вы используете дженерики без каких-либо ограничений, компилятор не будет знать, как работать с разными классами (даже если они были каким-то образом связаны). Подумайте, например, как компилятор узнает, что ApplyFilter будет работать как на классах Cat, так и на Dog? Для него собака и кошка - совершенно разные вещи.

Однако, учитывая, что оба ваших класса наследуются от одного и того же базового класса, вы можете работать с ними через их общий базовый класс (или интерфейс), но ваш класс PetFilter также должен быть общим.

public abstract class Pet 
{ 
} 

public class Dog : Pet 
{ 
} 

public class Cat : Pet 
{ 

} 

Ниже приведен общий класс PetFilter, он наследует IFilter, и даже если IFilter не имеет родовое ограничение, вы можете добавить один к классу PetFilter.

public class PetFilter<T> : IFilter<T> where T : Pet 
{ 
    public IEnumerable<T> ApplyFilter(IEnumerable<T> list) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Спасибо, к сожалению, я не могу сделать Generic PetFilter, поэтому я думаю, что ответ, вероятно, нет. Спасибо за тщательный ответ. –

2

Да, учитывая, что Dog и Cat оба наследуются от общего базового класса или реализуют общий интерфейс, например, IAnimal. Тогда, например:

private IEnumerable<T> ApplyFilter(IEnumerable<T> list) 
where T:IAnimal 
{ 
    // do the work here 
} 

Другими словами, если Cat и Dog разделяют логику фильтрации, это, безусловно, относится к общему основанию.

Смежные вопросы