【问题标题】:When should I provide a generic and non generic version of an interface?我什么时候应该提供接口的通用和非通用版本?
【发布时间】:2014-08-17 01:27:44
【问题描述】:

我了解对象的深克隆和浅克隆之间的区别,但根据 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
}

【问题讨论】:

标签: c# generics interface clone


【解决方案1】:

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

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

IEnumerableIEnumerable&lt;T&gt; 接口为例。泛型接口实现了非泛型接口,但只是为了提供与非泛型集合的向后兼容性:

理想情况下所有通用集合接口(例如ICollection&lt;T&gt;IList&lt;T&gt;) 将从它们的非泛型对应物继承,这样 泛型接口实例可以与泛型和 非通用代码。例如,如果IList&lt;T&gt; 可以传递给需要 IList 的代码。

【讨论】:

  • 感谢@Kyle 的建议编辑。我无法查看它们,因为我没有足够的积分,所以我手动进行了更改。
【解决方案2】:

正如那句话所说,如果您希望能够使用由具有不同类型参数的相同泛型定义生成的泛型类型集合,您确实必须提供非泛型接口。

考虑IDeepCloneable&lt;Widget&gt;IDeepCloneable&lt;Gadget&gt; 实例的列表。您始终可以将其设为List&lt;object&gt;,但除非您求助于运行时类型检查,否则您无法克隆它们。

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

如果您不打算以多态方式使用这些接口,那么使用非泛型 IDeepCloneable 不会提供任何东西。

【讨论】:

  • 哦!现在我明白了,所以当你想将不同的基本类型混合在一起时,你会使用非泛型版本......这就是接口的设计目的,哈。
猜你喜欢
  • 2010-12-13
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
相关资源
最近更新 更多