简体   繁体   中英

Generic interface implementing multiple generic types - how to share a method implementation?

Let's say I have the following interface

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

And a specific implementation like this:

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
    }
}

Is there any way to avoid having to implement separate methods for both Dog and Cat, given that they share the same implementation?

Yes, given that Dog and Cat both inherit from a common base class or implement a common interface like eg IAnimal . Then for instance:

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

In other words, if Cat and Dog share the filtering logic, it surely refers to a common base.

Yes and no. When you're using generics without any constraints the compiler would have no way of knowing of how to operate on the different classes (even if they were somehow related). Think for example how would the compiler know that ApplyFilter would work on both the Cat and the Dog classes? To it Dog and Cat are completely separate things.

However considering that both of your classes inherit from the same base class you can then operate on them through their common base class (or interface), but your PetFilter class would need to be generic as well.

public abstract class Pet
{
}

public class Dog : Pet
{
}

public class Cat : Pet
{

}

Below is a generic PetFilter class, it inherits IFilter, and even though IFilter doesn't have a generic constraint, you can add one to the PetFilter class.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM