简体   繁体   中英

How to constrain a generic collection to both a class name and an interface

Given public class BaseClass

that has derived classes, where a number of those follow the form

public class DerivedClass: BaseClass, ISpecificInterface

is there a way of specifying a collection that applies to just the derived classes that implement that interface?

For example, something like

public List<BaseClass where ISpecificInterface> myList; or

public List<BaseClass: ISpecificInterface> myList;

You can only constrain generic parameters, not generic arguments. So you'll need:

public class DerivedClassWithInterfaceListContainer<TDerived>
    where TDerived : BaseClass, ISpecificInterface
{
    public List<TDerived> MyList { get; set; }
}

You may want to inherit List<T> for this instead:

public class DerivedList<TDerived> : List<TDerived>
    where TDerived : BaseClass, ISpecificInterface
{    
}

And then you can use it as property type:

public DerivedList<SomeDerivedClass> MyList { get; set; }

Point being: you can only declare the list as containing one type. So if you want a list that can hold any class derived from BaseClass and implementing ISpecificInterface , you must do so in a method:

// either ISpecificInterface _or_ BaseClass
private List<ISpecificInterface> myList;

public void AddToList<TDerived>(TDerived toAdd)
    where TDerived : BaseClass, ISpecificInterface
{
    myList.Add(toAdd);
}

You could then combine this:

public class DerivedList : List<ISpecificInterface>    
{    
    public new void Add<TDerived>(TDerived toAdd)
        where TDerived : BaseClass, ISpecificInterface
    {
        this.Add(toAdd);
    }
}

But now someone can cast your DerivedList to IList<ISpecificInterface> and call Add() on that, with an object implementing ISpecificInterface but not inheriting from BaseClass .

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