【发布时间】:2013-12-04 13:18:51
【问题描述】:
我正在将现有的 .NET 类库移植到可移植类库。 .NET 库广泛使用了ICloneable 接口,该接口不包含在可移植子集中。
通常,我在 .NET 类库中会遇到这样的类定义:
public class Foo<T> where T : ICloneable
{
public void Bar(T item) {
var x = item.Clone();
...
}
}
如何才能成功将此代码移植到可移植类库?我是否必须重写 Clone 方法调用,还是有不那么侵入性的解决方法?
我不能简单地删除泛型类型约束where T : ICloneable,因为那样Bar 方法将无法编译。
我可以编写一个替换接口来代替移植代码中的ICloneable:
public interface IPCLCloneable {
object Clone();
}
只要我只使用实现 IPCLCloneable 的类来实例化 Foo<T>,它就可以工作,但它不会工作,例如来自实现 ICloneable 的核心库中的类型,例如如Array:
var x = new Foo<int[]>(); // Compilation error in PCL library
(为了完整起见,应该指出ICloneable接口在可移植子集核心库中没有显式实现,因为它不存在,但object Clone()方法确实存在于可移植子集Array类中,因此对于数组实现,例如int[]。)
我还有什么其他选择?
【问题讨论】:
-
这是个好问题。但是,您是否不必编写一个“新的” int[] 类来实现它的 Clone 方法?或者 PCL 是否有 int[].Clone() 没有 实现 ICloneable?我还可以想象您可以删除约束,并首先尝试 ICloneable ,并有一个替代实现作为后备。不是很漂亮,它会消除约束的一个好处(编译时类型检查),但这很可能是你必须付出的代价......
-
@Luaan 是的,
int[].Clone()在 PCL 中可用,只是ICloneable接口不存在。并感谢您的建议。当然,“越漂亮”越好,但最终我可能不得不做一些重大的重构...... -
嗯,这很烦人。似乎您可能必须使用反射,或者为所有已知的原始类型编写包装器 - 而不是使用 int[] 作为泛型类型,您必须传递 Cloneable
。考虑一下,使用包装器可能是最好的方法 - 它仍然可以为您提供编译时类型检查,而且开销很小...... -
是的,我也考虑过包装器。谢谢@Luaan 的建议。
-
@qujck 如果我在 .NET 应用程序中使用 PCL,那将不起作用,因为那样我会有重复的接口。这也无助于与
int[].Clone()和类似情况相关的场景。
标签: c# generics interface portable-class-library icloneable