我应该何时提供接口的通用和非通用版本?

时间:2014-06-26 08:58:36

标签: c# generics interface clone

我理解对象的深度和浅层克隆之间的区别,但根据Simon对this (copy-constructor-versus-clone)问题的回答,应该提供通用和非泛型版本。为什么呢?

  

您可以定义两个接口,一个用于支持强类型克隆的通用参数,另一个用于在处理不同类型的可克隆对象的集合时不保留弱类型克隆功能:

我的意思是制作不同的接口是微不足道的,但在现代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
}

2 个答案:

答案 0 :(得分:5)

正如该引言所说,如果您希望能够使用具有不同类型参数的相同通用定义生成的泛型类型集合,则必须提供非泛型接口。

考虑IDeepCloneable<Widget>IDeepCloneable<Gadget>个实例的列表。您始终可以将其设为List<object>,但除非您使用运行时类型检查,否则无法克隆它们。

如果您希望能够以多态方式克隆(或者通常以其他方式访问)这些项目,则需要对它们进行类型化,以便它们的静态类型提供最小的公共接口,以便您完成工作。在这种情况下,这将使我们的列表成为List<IDeepCloneable>

如果您不打算以多态方式使用这些接口,则使用非通用IDeepCloneable不会提供任何内容。

答案 1 :(得分:1)

你回答了自己的问题。 :)

您需要使用非通用版本来处理非泛型集合。

IEnumerableIEnumerable<T>接口为例。通用接口实现非泛型接口,但仅提供与非泛型集合的向后兼容性:

  

理想情况下所有通用集合接口(例如ICollection<T>,   IList<T>)将继承其非通用对应物,以便   通用接口实例可以与泛型和。一起使用   非通用代码。例如,IList<T>会很方便   可以传递给期望IList的代码。