什么时候我应该提供一个接口的通用和非通用版本
本文关键字:接口 版本 一个 我应该 什么时候 | 更新日期: 2023-09-27 18:10:31
我理解对象的深层克隆和浅层克隆之间的区别,但根据Simon对这个(复制构造函数与克隆)问题的回答,应该提供一个泛型和非泛型版本。为什么?
我的意思是,制作不同的接口已经足够琐碎了,但是在现代c#的泛型范式中,我发现很难想出一个合理的理由,为什么要使用非泛型和弱类型的版本。见鬼,你甚至可以有可以定义两个接口,一个带泛型参数以支持强类型克隆,另一个不带泛型参数以保留弱类型克隆能力,以便在处理不同类型可克隆对象的集合时使用:
T:object
做同样的事情!我会这样写我的接口:
public interface IShallowCloneable
{
object Clone();
}
public interface IShallowCloneable<T> // Should this derive IShallowCloneable?
{
T Clone();
}
public interface IDeepCloneable
{
object Clone();
}
public interface IDeepCloneable<T> // Should this derive IDeepCloneable?
{
T Clone();
}
我的类会这样实现它:
public class FooClass : IDeepCloneable<FooClass>
{
// Implementation
}
正如上面引用的那样,如果您希望能够使用由相同泛型定义产生的泛型类型集合,但具有不同的类型参数,那么您确实必须提供一个非泛型接口。
考虑IDeepCloneable<Widget>
和IDeepCloneable<Gadget>
实例的列表。您总是可以将其设置为List<object>
,但是这样您就不能克隆它们,除非您诉诸于运行时类型检查。
如果您希望能够以多态方式克隆(或通常以其他方式访问)这些项,则需要对它们进行类型化,以便它们的静态类型提供允许您完成该工作的最小公共接口。在本例中,这将使我们的列表为List<IDeepCloneable>
。
如果你不打算多态地使用这些接口,那么拥有一个非通用的IDeepCloneable
并不能提供任何东西。
你回答了你自己的问题。:)
你需要非泛型版本来处理非泛型集合。
以IEnumerable
和IEnumerable<T>
接口为例。泛型接口实现非泛型接口,但仅提供与非泛型集合的向后兼容性:
理想情况下,所有的通用集合接口(例如
ICollection<T>
,IList<T>
)将从它们的非泛型对应物继承,这样泛型接口实例可用于泛型和非泛型代码。例如,如果使用IList<T>
可以传递给需要illist的代码