我有一个有趣的问题,我一直在盘旋,但我似乎从来没有安静地找到解决方案。
我倾向于成为一名防御型程序员,因此我尝试编写代码来防止问题发生,而不是在问题发生后才使用react。为此,我有以下情况。采取以下代码:
public class Base {}
public Interface IBase {}
public class Derived : Base, IBase {}
public class Derived2 : Base, IBase {}
...
public class DerivedN : Base, IBase {}
public class X : Base {}
public class Y : IBase {}
我需要将派生自 Base 并实现 IBase 的对象列表传递给一个集合,并且我需要确保只有同时具有这两者的对象才会添加到列表中。此外,可以有任意数量的类同时具有两者,因此我不能使用派生类作为约束。
如果我创建 Base 类型的列表,那么我可以添加一个 Y 对象。如果我将其设为 IBase 类型,则可以添加 X 类型的对象(两者均不允许)。
当然,我可以创建自己的通用集合类,它具有两种类型并且对两种类型都有约束。但是,我不想对所有可能的集合类型都这样做,而且复制所有这些功能需要付出很多努力(即使您只是将方法调用转发给包含的类)。
我还可以创建一个 BaseWithIBase 类,它派生自 Base 和 IBase,并将其用作我的集合类型,但如果没有必要,我真的不想强制另一个抽象。
我不希望这是运行时检查,因此遍历树并抛出异常是 Not Acceptable 。
谁能建议一个更好的方法来解决这个问题?
注意:Base 和 IBase 没有关系,只是指出它们都是不同类型的基础项。
编辑:
似乎每个人都想坚持“你不需要那样做”和“不是OOP”。没有东西会离事实很远。我试图从问题中删除具体内容以防止此类问题和评论,因此我将包括我的真实情况。
该代码是基于 .NET Frameworks ServiceProcess.ServiceBase 类的 Windows 服务框架的实现。我在此基础上添加了我自己的框架,旨在高度依赖注入(inject)和高度可测试。
该集合必须包含派生自 ServiceBase 和 IService 的对象。 IService 是我的代码中使用的框架扩展,用于测试。基本上就是这样:
public interface IService
{
void Start();
void Stop();
}
除此之外,我还有一些其他接口(interface):
public interface IRestartableService
{
void Restart();
}
public interface IConfigurableService
{
void Configure();
}
等.. 等..服务可能如下所示:
public class MyService : ServiceBase, IService, IConfigurableService {}
我的代码需要 IService,Windows 需要 ServiceBase,因此两者都是必需的,因为我使用 IService,而 Windows 使用 ServiceBase。我只需要IService,其他接口(interface)可选。
最佳答案
您可以简单地创建自己的包装器集合:
// TODO: Work out which collection interfaces you want to implement
public class BaseList
{
// Or use List<IBase>, if that's how you'll be using it more often.
private List<Base> list = new List<Base>();
public void Add<T>(T item) where T : Base, IBase
{
list.Add(item);
}
}
通过使用具有两个约束的通用方法,您可以确定 Add
只能使用适当的类型参数调用。
您可以使用两种方法将数据公开为 IEnumerable<T>
- 一个返回 IEnumerable<IBase>
(使用 Cast<T>
)和一个返回 IEnumerable<Base>
...这将允许您在任一 类型上使用 LINQ,当然不能同时使用这两种类型。
我怀疑您可能会在其他地方发现这很尴尬,但是 - 您可能会发现自己在代码中使用了通常不需要的通用方法。虽然同时需要类部分和接口(interface)部分可能有充分的理由,但值得退后一步并考虑它们是否真的都是必要的。例如,您是否可以向界面添加一些额外的东西,以便您可以取消类约束?
关于c# - 确保泛型集合包含派生自两个基础对象的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17037202/