条件类型约束参数
本文关键字:参数 约束 类型 条件 | 更新日期: 2023-09-27 18:03:31
我有一个类Container
我想确保如果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继承自它。使它抽象,确保没有人使用它,而不是你的具体实现。