我正在尝试创建一个名为 ForumHolderAdminController 的类。 ForumHolderAdminController 为父类CmsAdminController 提供了 Controller 类型的集合。
我有以下代码:
public abstract class CmsAdminController : Controller {
// The type of child controllers allowed
protected Collection<Type> AllowedChildren {
get { return null; }
}
}
public class ForumHolderAdminController : CmsAdminController {
protected new Collection<Type> AllowedChildren {
get {
Collection<Type> allowedChildren = new Collection<Type> {
typeof(ThreadHolderController)
};
return allowedChildren;
}
}
}
我想限制开发人员传递实现 IController 接口(interface)的类型集合。类似于以下内容:
protected new Collection<IController> AllowedChildren {
get {
Collection<IController> allowedChildren = new Collection<IController> {
typeof(ThreadHolderController)
};
return allowedChildren;
}
}
显然,代码示例将无法运行,因为没有创建实例。但我想要与此类似的东西,您不必创建对象的实例,只需传递类型即可。
我确实看到了以下似乎有些相关的问题,但是其中一条评论建议在将类型添加到集合之前使用静态分析: Type-safe collection of Type class with defined base type
如果我必须执行静态分析,这就会给我带来麻烦。如果开发人员传递了一个尚未实现 IController 接口(interface)的类型,我们在代码执行之前不会知道代码有问题。我更希望有一个编译错误阻止开发人员传递一个或多个不实现 IController 接口(interface)的类型集合。
因此,是否可以限制开发人员传递实现 IController 接口(interface)的类型集合?
最佳答案
您可以通过返回一个包装类型的自定义类来非常接近您想要做的事情,并且只能为实现 IController 的泛型类型实例化:
public class ControllerTypeWrapper<T> : ControllerTypeWrapper
where T : IController
{
public Type Type {get {return typeof(T);}}
}
public class ControllerTypeWrapper
{
// This should only be extended by ControllerTypeWrapper<T>
internal ControllerTypeWrapper(){}
}
然后是你的AllowedChildren property should return these wrappers, and whatever's consuming it can simply use the
结果的 .Type` 属性:
protected new IReadOnlyCollection<ControllerTypeWrapper> AllowedChildren {
get {
return new List<ControllerTypeWrapper> {
new ControllerTypeWrapper<ThreadHolderController>()
};
}
}
Note: You probably don't actually intend to have this property be
new
. Consider making the parent class's propertyabstract
so you can force the child classes tooverride
it.
另一种选择是使用 Alex Voskresenskiy 的方法,使用 RegisterType<T>()
方法,但在那种情况下,您可能希望该方法受到保护,并期望您的子类的构造函数调用 RegisterType<>()
使用您想要允许的任何子类型。这样做的缺点是每次构造 Controller 时您都在做这项工作,而您可能只需要一次。
可能还有其他更好的选择,例如使用自定义属性和使用简单的单元测试来检查所有 Controller 上的所有属性是否具有适当的类型。但如果不进一步了解您打算如何使用这些数据,就很难说。
关于c# - 实现特定接口(interface)的类型集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29238099/