我认为对泛型参数施加约束没有错。有一个通用的参数并不意味着“这对任何事情都有效”,它意味着有不止一种方法可以使代码有意义。
它实际上可能会公开一个完全通用的概念,例如List<T>
,但它可能会公开一个仅在某些上下文中有意义的概念(例如Nullable<T>
仅对不可为空的实体有意义)
约束只是您用来告诉世界在什么情况下该类有意义的机制,并使您能够以合理的方式实际使用该(受约束的)参数,即调用Dispose
实现的事物IDisposable
极端情况是当上下文非常受限时,即如果只有两种可能的实现怎么办?实际上,我当前的代码库中有这种情况,并且我使用泛型。我需要对某些数据点进行一些处理,目前(以及在可预见的将来)只有两种数据点。原则上,这是我使用的代码:
interface IDataPoint
{
SomeResultType Process();
}
class FirstKindDataPoint : IDataPoint
{
SomeResultType Process(){...}
};
class SecondKindDataPoint : IDataPoint
{
SomeResultType Process(){...}
};
class DataPointProcessor<T> where T: IDataPoint
{
void AcquireAndProcessDataPoints(){...}
}
即使在这种受限的环境中,这也是有道理的,因为我只有一个处理器,所以只有一个逻辑需要处理,而不是我必须尝试保持同步的两个单独的处理器。
这样,我可以在处理器中使用 aList<T>
和 an而不是 a and在我的场景中这将是不正确的,因为我需要一个处理器来处理更具体的数据类型,即实现.Action<T>
List<IDataPoint>
Action<IDataPoint>
IDataPoint
如果我需要一个可以处理任何东西的处理器,只要它是一个,删除它的通用性并简单地在代码中IDataPoint
使用可能是有意义的。IDataPoint
此外,@dasblinkenlight 的回答中提出的观点非常有效。如果泛型参数既可以是结构也可以是类,那么使用泛型将避免任何装箱。