繁体   English   中英

有什么方法可以将通用接口限制为实现它的类型?

[英]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 BadFooclass AlsoBad class BadFooClone()实现的“确保未经证实”的警告。

因为有Contract.Assume(result.GetType() == this.GetType());所以没有针对GoodFoo.Clone()警告Contract.Assume(result.GetType() == this.GetType()); 在执行中。

但是,我认为“代码合同静态检查”仍然太慢,除了偶尔检查之外,对于其他任何事情来说,但是您的里程可能会有所不同...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM