I want to create a code contract for a certain interface, however I'm having a hard time believing that it is actually done this way.
[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);
}
}
The contract should ensure that 1) all classes implementing the interface require the argument key to be not null or empty as well as to 2) auto-generate the check into the build, e.g. similar to
public Task<bool> GetAsync<T>(string key, out T value) {
if(String.IsNullOrEmpty(key))
throw new ArgumentException //...
}
However in this particular case, it feels strange to me that I have to assign the out argument as well as return a dummy Task just to make the compiler happy. Is there no more straightforward way, e.g. using attributes?
You don't have to, if you
throwan exception instead ofreturn-ing from the method. Then you don't have to construct a return value, nor do you need to assign to theoutparameter:In fact, this is semantically more correct than returning from the method. Why? Because no-one is meant to actually call these contract methods. They were never supposed to do any meaningful work, so they don't need to return any meaningful values. All that is required of your contract class is that it declares the contracts; the actual work is done somewhere else.