c# - 确保泛型集合包含派生自两个基础对象的对象

标签 c# type-constraints

我有一个有趣的问题,我一直在盘旋,但我似乎从来没有安静地找到解决方案。

我倾向于成为一名防御型程序员,因此我尝试编写代码来防止问题发生,而不是在问题发生后才使用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/

相关文章:

haskell - applicative 到底有多重要,而不是 "combining"?

C# ListView 项目图像

c# - 制作一个类,每个属性拥有不同数量的设置通用?

c# - 使用 Linq 比较 2 个列表

swift - 如何为可添加参数创建通用函数?

c# - 将方法的类型参数限制为另一种类型实现的接口(interface)

c# - 异步/等待的优缺点

javascript - 使用某些参数滚动到 View

ios - 通用闭包的 Swift 数组?

perl - Moose 从单个参数构造对象