说我有以下
public T Example(Func<T> f)
{
Contract.Requires(f != null);
Contract.Requires(f() != null); // no surprise, this is an error
...
}
有没有办法指定我的Func<T>
参数必须遵守某些合同?
答案 0 :(得分:2)
一般来说,这似乎是一个有问题的要求,因为调用f
可能会引入副作用,因此指定合同可能会影响方法的作用。
作为Code Contracts库的实现者,可以引入包装器代码,该代码检查f
的值是否在方法的上下文中调用时遵守合同(以避免引入虚假方法调用) )。出于以下几个原因,这是有问题的:
f
,因此调用方可能违反合同而不会被破坏。f
的调用不符合规范的情况下执行其他可能无效的工作后,该方法才能调用f
。如果f
没有副作用,那么这些就不会出现问题,但是如果总是调用f
来处理1的副作用会出现问题,那么就会调用f
在做任何处理2的工作之前也不会飞。
因此,总而言之,我认为这不可能(在本机代码合同的背景下)并且有充分的理由。
答案 1 :(得分:1)
如果您的意思是传递的方法应检查自己是否例如参数不为null,不能你不能这样做。合同仍然只是将代码添加到方法体。
您可以做的是将委托包装到不同的委托中,例如:
public T Example<T, TResult>(Func<T, TResult> f)
where T : class
where TResult : class
{
Contract.Requires(f != null);
f = WrapWithContracts(f);
// ...
}
private Func<T, TResult> WrapWithContracts<T, TResult>(Func<T, TResult> f)
where T : class
where TResult : class
{
return p =>
{
Contract.Requires(p != null);
Contract.Ensures(Contract.Result<TResult>() != null);
var result = f(p);
return result;
};
}
这样您就可以自己引入代码合同。
答案 2 :(得分:0)
如果(如此处)它是您所关注的特定无效,ReSharper(从4.0开始)支持注释,例如CanBeNull
和NotNull
,可以作为方法的属性放置,之后R#可以警告可能的空解除引用操作。