Is List <System.Type> that only allows certain types?

is it possible to have a general List<System.Type>

and have a constraint on the type? I want to store types in a searchable list, but only types where a class of that type implements a certain interface.

Something like that:

List<Type> : where typeof(Type) is IMyClass

      

Is it possible? If you have no suggestion on how to fix this problem?

Any help is appreciated!

EDIT:

Sorry that I was not clearer on this, but below is the comment below, I have no instances available, just enter.

Let's assume the following:

class PluginA : IPlugin { } 
class PluginB : IPlugin { } 
class PluginC : ISomeOtherInterface { } 

var pluginTypes = new List<Type>()
pluginTypes.Add(typeof(PluginA) --> OK
pluginTypes.Add(typeof(PluginB) --> OK
pluginTypes.Add(typeof(PluginC) --> should fail

      

Yes, I could wrap this up, but hoped there would be a better option that checks at compile time or hints with intellisense what types are allowed.

+2


source to share


7 replies


If you read it right, you need a System.Type list that checks that its members implement a specific interface. It's easy to do. Just implement IList<Type>

by wrapping most of the functions List<Type>

and add a couple of checks.

public class TypeFilteredList : IList<Type>
{
    private Type filterType;
    private List<Type> types = new List<Type>();

    public TypeFilteredList(Type filterType)
    {
        this.filterType = filterType;
    }

    private void CheckType(Type item)
    {
        if (item != null && !filterType.IsAssignableFrom(item))
            throw new ArgumentException("item");
    }

    public void Add(Type item)
    {
        CheckType(item);
        types.Add(item);
    }

    public void Insert(int index, Type item)
    {
        CheckType(item);
        types.Insert(index, item);
    }

      

...

}

      



this code will work for both base classes and interfaces.

Usage example:

TypeFilteredList list = new TypeFilteredList(typeof(IInterface));
list.Add(typeof(Implementation));
list.Add(typeof(int)); // ArgumentException

      

If you don't need features IList

, you can implement IEnumerable<Type>

or ISet<Type>

(wrapping HashSet<T>

). The list leaves the possibility of adding the same type several times, which I don't think is necessary.

+7


source


Well, you can write your own wrapper:

public class ConstrainedList<T> where T : IMyClass
{
    private List<T> list;

    // Access the list however you want
}

      



You cannot add restrictions to List<T>

yourself.

You might want to expose the wrapped list directly, or you can implement IList<T>

and simply delegate each member to the list. It's hard to say without knowing more about what you are trying to achieve.

+5


source


Ok, I usually didn't do this (the answer is so trivial), but since no one suggested the most obvious answer ... Inheritance.

public sealed class IMyClassList : List<IMyClass> { }

      

Done and done.

+2


source


You can specify any type for List

, so yes:

List<IMyClass> myClassList = new List<IMyClass>();

      

+1


source


You can try using generics like this:

 class EmployeeList<T> where T : IMyClass
 {
     // ...
 }

      

+1


source


Yes - do that List<IMyClass>

, then you can keep any instance that implements this interface.

+1


source


I only see one way to check it at compile time. You can create a class derived from a list and write your own generic Add method to do this.

Something like that:

class PlugginsList : List<Type>
{
  public void Add<T>()
    where T : IPlugin
  {
    Add(typeof(T));
  }
}

var plugginList = new PlugginsList();
plugginList.Add<PluginA>() --> OK
plugginList.Add<PluginB>() --> OK
plugginList.Add<PluginC>() --> will fail

      

You will achieve all your goals using a common method: ie, compile time, intellisense, and all other chasing tools provided by Visual Studio and the C # compiler

+1


source







All Articles