条件类型约束参数

本文关键字:参数 约束 类型 条件 | 更新日期: 2023-09-27 18:03:31

我有一个类Container,它有一个containercontent。容器实际上有两个类型约束参数Container<TContainer,>- TContainer是容器的类型,TContents是容器接受的内容类型。

我想确保如果TContainer是X或从X派生,那么TContents也将是X或从X派生,但TContents不必等于TContainer。

我在试着表达以下几种东西。

  • 可以随身携带的东西(Swag),比如铅笔。
  • 不能携带的东西(BaseObject),如树。
  • 可以容纳其他物品的物品(容器)
  • 不能携带的集装箱,如银行金库。
  • 可携带容器(如背包)。

如果一个容器可以携带,那么它的内装物也必须可以携带。但是,仅仅因为Container是一个背包并不意味着它只能携带背包。

我想要能够编码:

  • var ringWorld = new Container<BigRing, CivicWork>();
  • var pickleKnox = new Container<BankVault, Pickle>();
  • var swagBag = new Container<ToteBag, Swag>();
  • var tomeBag = new Container<ToteBag, Book>();

但不包括var treeBag = new Container<Bag, Tree>();

这是我的框架设置。

public abstract class BaseObject
{
    private readonly string _name;
    protected BaseObject(string name)
    {
        _name = name;
    }
    public string Name { get { return _name; } }
}
public class Swag : BaseObject
{
    private readonly int _weight;
    public Swag(string name, int weight):base(name)
    {
        _weight = weight;
    }
    public int Weight { get { return _weight; } }
}
/* I like the flexibility of i.e.: Container<BankVault,Pickles> 
but if the container itself is carriable (Swag), then its contents 
are by nature also carriable. */
public class Container<TContainer,TContents> : BaseObject 
    where TContainer:BaseObject 
    where TContents:BaseObject, or Swag if TContainer:(Swag or derived from Swag)
{
    ContainerContents<TContents> _contents;
    public Container(string name, int maxItems):base(name)
    {
        /* if (TContainer is derived from Swag) { TContents must be too } */
        _contents = new ContainerContents<TContents>(maxItems);
    }
}
公共类ContainerContents<: Listwhere T: BaseObject{int _maxItems;public ContainerContents(int maxItems){_maxItems = maxItems;}} 

条件类型约束参数

我觉得这样不行。

我将创建以下接口:
interface ICarryable { }
interface IContainer<T> { }

那么你可以实现以下类:

class Backpack<T> : ICarryable, IContainer<T>
where T : ICarryable 
{  }
class Vault<T> : IContainer<T>
{  }

如果一个类实现了ICarryable,它可以被携带。如果它不实现那个接口,它就是一个不能携带的固定对象。这更准确地描述了正在发生的事情。你的通用Container类不通信,容器的类型是TContainer和它的内容类型是TContainerContents

为了避免违反DRY原则,您仍然可以创建一个泛型容器基类,您的vault和backpack继承自它。使它抽象,确保没有人使用它,而不是你的具体实现。