我想使用 CloneInstance 方法创建接口(interface),该方法返回该实例的通用类。例如:
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>
明确地。一个不那么令人困惑的方法(对于谁实现这个接口(interface)以及谁将使用它)是提供一个扩展方法:
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
,但如果您不想使用它,因为它在世界范围内随机使用,那么只需选择您自己的等效非通用接口(interface)即可)。
关于c# - 通用克隆实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33754866/