是列表<;系统类型>;它只接受某些可能的类型

本文关键字:类型 lt 列表 系统 gt | 更新日期: 2023-09-27 18:26:23

是否有可能拥有泛型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提示允许哪些类型。

是列表<;系统类型>;它只接受某些可能的类型

如果我理解正确,你需要一个System.Type列表,它检查它的元素是否实现了某个接口。这很容易实现。只需通过封装大部分List<Type>功能并添加几个检查来实现IList<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>)。List留下了一个选项,可以多次添加相同的类型,在我看来这是你不想要的。

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

public class ConstrainedList<T> where T : IMyClass
{
    private List<T> list;
    // Access the list however you want
}

但是,您不能向List<T>本身添加约束。

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

好吧,我通常不会这么做(答案很琐碎),但由于没有人提出最明显的答案。。。遗产

public sealed class IMyClassList : List<IMyClass> { }

完成了,完成了。

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

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

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

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

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

我只看到一种在编译时检查它的方法。您可以创建从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

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