繁体   English   中英

了解接口的代码协定

[英]Understanding code contracts for interfaces

我想为某个接口创建代码协定,但是我很难相信它实际上是通过这种方式完成的。

[ContractClass(typeof(AsyncCacheProviderContract))]
public interface IAsyncCacheProvider {

    Task<bool> GetAsync<T>(string key, out T value);

}

[ContractClassFor(typeof(AsyncCacheProviderContract))]
internal abstract class AsyncCacheProviderContract : IAsyncCacheProvider {

    public Task<bool> GetAsync<T>(string key, out T value)
    {
        Contract.Requires(!String.IsNullOrEmpty(key));

        value = default(T);
        return Task.Factory.StartNew(() => false);
    }

}

合同应确保1)所有实现该接口的类均要求参数不能为null或为空,以及2)自动将检查生成到版本中,例如类似于

public Task<bool> GetAsync<T>(string key, out T value) {
    if(String.IsNullOrEmpty(key))
        throw new ArgumentException //...
}

但是,在这种特殊情况下,我感到很奇怪,我必须分配out参数并返回一个哑Task以使编译器满意。 还有没有更直接的方法,例如使用属性?

我感到很奇怪,我必须分配out参数并返回一个哑任务,以使编译器满意。

如果您throw了异常而不是从方法中return -ing,则不必这样做。 然后,您不必构造返回值,也不必分配给out参数:

[ContractClassFor(typeof(IAsyncCacheProvider))] // note: there's a small change here!
sealed class AsyncCacheProviderContract : IAsyncCacheProvider
{
    public Task<bool> GetAsync<T>(string key, out T value)
    {
        Contract.Requires(!String.IsNullOrEmpty(key));
        throw new NotSupportedException(); // makes the compiler happy, too
    }

    private AsyncCacheProviderContract() { } // optional safeguard:
}                                            // prevent instantiation (see below)

实际上,从语义上讲,这比从方法中返回更正确。 为什么? 因为没有人会真正调用这些合同方法。 他们从不应该做任何有意义的工作,因此他们不需要返回任何有意义的值。 您的合同类别所需要的就是声明合同。 实际工作在其他地方完成。

相关问题:
非无效接口代码契约的实现-default(T)vs throw NotImplementedException

暂无
暂无

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

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