我想用CloneInstance方法创建接口,该方法返回该实例的通用类。例如:
public interface ICloneableExtended<T> where T : this
{
T CloneInstance();
}
public class Car : ICloneableExtended
{
...
...
public Car CloneInstance()
{ .. }
}
Foo()
{
Car car ...;
var clonedCar = car.CloneInstance();
}
在类
Car
的定义中,我只需要使用ICloneableExtended
,而不是ICloneableExtended<T>
。有什么办法可以做到这一点? 最佳答案
您可以为将实现T
的具体类接受通用的ICloneableExtended
参数:
interface ICloneableExtended<T> {
Clone();
}
class Car : ICloneableExtended<Car> {
public Car Clone() {
throw new NotImplementedException();
}
}
您可以考虑使
T
参数为协变变量(如果您希望将ICloneableExtended<Car>
保留为许多具体的类-将实现ICloneableExtended<T>
):interface ICloneableExtended<out T> {
Clone();
}
请注意,您可能不需要通用类接口,而您已经有了
ICloneable
(具有所有缺点和误用):interface ICloneableExtended<out T> : ICloneable {
Clone();
}
对于二进制可序列化类型,您甚至可以实现一个基本且可重用(但效率很低)的基类:
interface ICloneableExtended<T> : ICloneable {
T Clone();
}
abstract class Cloneable<T> : ICloneableExtended<T> {
public virtual T Clone() {
using (var ms = new MemoryStream()) {
var formatter = new BinaryFormatter();
formatter.Serialize(ms, this);
ms.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(ms);
}
}
object ICloneable.Clone() {
return Clone();
}
}
sealed class Car : Cloneable<Car> { }
使用这种方法,每个具体的类都必须实现
ICloneableExtended<T>
,但是您不能重载Clone()
方法,仅用返回值来区分,然后最好显式实现ICloneableExtended<T>
。较少混淆的方法(对于谁实现此接口以及谁将使用它)都是提供扩展方法:static class Extensions {
public static T Clone<T>(this object obj) {
var cloneable = obj as ICloneable;
if (cloneable != null)
return (T)cloneable.Clone();
using (var ms = new MemoryStream()) {
return (T)...
}
}
}
(在这里我使用
ICloneable
是为了清楚起见,但是如果您由于世界范围内的随机使用而不想使用它,那么只需选择自己的等效非通用接口即可)。关于c# - 通用CloneInstance,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33754866/