List <system.type>是否只接受某些类型?</system.type>

时间:2012-03-02 15:33:23

标签: c#

是否有可能拥有通用List<System.Type>并对类型有约束? 我希望将类型存储在列表中以进行查找,但仅限于此类类实现特定接口的类型。

这样的事情:

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

这可能吗?如果没有,你对如何解决这个问题有任何建议吗?

任何帮助表示赞赏!

修改

对不起,我对这个问题一直不太清楚,但下面的Sign的评论是正确的,我没有可用的实例,只是类型。

假设如下:

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

是的我可以包装它,但希望有一个更好的变体,它在编译期间检查或提示intellisense允许哪些类型。

7 个答案:

答案 0 :(得分:7)

如果我理解正确,你需要一个System.Type列表,它检查它的元素是否实现了某个接口。这很容易实现。只需通过包装大多数IList<Type>功能并添加几个核对来实现List<Type>

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

...

}

此代码适用于基类和接口。

使用示例:

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

如果您不需要IList功能,则可以实施IEnumerable<Type>ISet<Type>(包裹HashSet<T>)。列表留下了一个选项,可以多次添加相同的类型,在我看来,这是你不想要的东西。

答案 1 :(得分:5)

你可以编写自己的包装器:

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

    // Access the list however you want
}

您无法向List<T>本身添加约束。

可能希望直接公开包装列表,或者您可能希望实现IList<T>并将每个成员委派给列表。如果不了解更多关于你想要实现的目标,很难说。

答案 2 :(得分:2)

好吧,我通常不会这样做(答案是如此微不足道),但是没有人提出最明显的答案......继承。

public sealed class IMyClassList : List<IMyClass> { }

完成并完成。

答案 3 :(得分:1)

您可以为List指定任何类型,所以是:

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

答案 4 :(得分:1)

您可以尝试使用这样的泛型:

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

答案 5 :(得分:1)

是 - 将其设为List<IMyClass>,然后您可以存储实现该接口的任何实例。

答案 6 :(得分:1)

我只看到一种在编译时检查它的方法。 您可以创建从List派生的类,并编写自定义通用Add方法来执行此操作。

这样的事情:

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

您将通过使用通用方法实现所有目标,即编译时间检查,智能感知和Visual Studio和C#编译器提供的所有其他类型的cheking工具