[英]Any way to constrain a generic interface to the type that implements it?
public interface ICloneable<T>
{
T Clone();
}
public Foo: ICloneable<Foo>
{
public Foo Clone()
{
//blah
}
}
有什么方法可以将T
约束为实现接口的类型? (在这种情况下为Foo
)。 最好强制实施任何实现ICloneable
以返回其自身的实例,而不是它所希望的任何随机类型。
不,基本上。 您不能在通用约束下做到这一点。 另外,您不能停止使用不同的T
多次实现接口(只要那些T
满足任何where
约束,在这种情况下都不满足)。
没有where
约束可以限制实现类型。
您可以将它作为方法参数限制来执行,但并不能令人满意:
public static T SuperClone<T>(this T original) where T : ICloneable<T> {...}
请注意,可以使用代码合同来表达这一点。 通常,这是在运行时检查的,但是有可能得到编译时警告(请参阅后面的注释):
它是这样的:
[ContractClass(typeof(CloneableContract<>))]
public interface ICloneable<out T>
{
T Clone();
}
[ContractClassFor(typeof(ICloneable<>))]
internal abstract class CloneableContract<T>: ICloneable<T>
{
public T Clone()
{
Contract.Ensures(Contract.Result<object>() != null);
Contract.Ensures(Contract.Result<object>().GetType() == this.GetType());
return default(T);
}
}
然后,如果您具有以下类定义:
public class GoodFoo: ICloneable<GoodFoo>
{
public virtual GoodFoo Clone()
{
var result = new GoodFoo();
Contract.Assume(result.GetType() == this.GetType());
return result;
}
}
public class BadFoo: ICloneable<object>
{
public object Clone()
{
return new object(); // warning : CodeContracts: ensures unproven: Contract.Result<object>().GetType() == this.GetType()
}
}
public class AlsoBad: GoodFoo
{
public override GoodFoo Clone()
{
return new GoodFoo(); // warning : CodeContracts: ensures unproven: Contract.Result<object>().GetType() == this.GetType()
}
}
这将在运行时正常运行:
var good = new GoodFoo();
good.Clone();
这些将导致运行时代码协定失败:
var bad = new BadFoo();
bad.Clone();
var alsoBad = new BadFoo();
alsoBad.Clone();
需要注意的是,你可以得到一个编译时实时预警。
如果您执行完整的代码合同静态检查编译,您将看到有关class BadFoo
和class AlsoBad
class BadFoo
的Clone()
实现的“确保未经证实”的警告。
因为有Contract.Assume(result.GetType() == this.GetType());
所以没有针对GoodFoo.Clone()
警告Contract.Assume(result.GetType() == this.GetType());
在执行中。
但是,我认为“代码合同静态检查”仍然太慢,除了偶尔检查之外,对于其他任何事情来说,但是您的里程可能会有所不同...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.