我想为某个界面创建一个代码契约,但是我很难相信它实际上是这样做的。
[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)实现接口的所有类都要求参数 key 不为null或为空以及2)自动生成对构建的检查,例如:类似于
public Task<bool> GetAsync<T>(string key, out T value) {
if(String.IsNullOrEmpty(key))
throw new ArgumentException //...
}
然而在这种特殊情况下,我感到很奇怪,我必须分配out
参数以及返回一个虚拟Task
只是为了让编译器满意。有没有更简单的方法,例如使用属性?
答案 0 :(得分:2)
我感到很奇怪,我必须分配out参数以及返回一个伪任务,以使编译器满意。
如果您从方法中throw
例外而不是return
,则不必如此。那么你不必构造一个返回值,也不需要分配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)
实际上,这在语义上比从方法返回更正确。为什么?因为没有人打算实际调用这些合同方法。他们从不应该做任何有意义的工作,因此他们不需要返回任何有意义的价值观。合同类所要求的只是它宣布合同;实际的工作是在其他地方完成的。
相关问题:
Implementation of non-void interface Code Contracts - default(T) vs throw NotImplementedException