如何避免“source !=null”当使用代码契约和 Linq To Sql 时?
我有以下使用正常数据上下文的代码,效果很好:
var dc = new myDataContext();
Contract.Assume(dc.Cars!= null);
var cars = (from c in dc.Cars
where c.Owner == 'Jim'
select c).ToList();
但是,当我将过滤器转换为这样的扩展方法时:
var dc = new myDataContext();
Contract.Assume(dc.Cars!= null);
var cars = dc.Cars.WithOwner('Jim');
public static IQueryable<Car> WithOwner(this IQueryable<Car> cars, string owner)
{
Contract.Requires(cars != null);
return cars.Where(c => c.Owner == owner);
}
我收到以下警告:
警告:CodeContracts:需要未经验证:源!= null
I have the following code using a normal data context which works great:
var dc = new myDataContext();
Contract.Assume(dc.Cars!= null);
var cars = (from c in dc.Cars
where c.Owner == 'Jim'
select c).ToList();
However when I convert the filter to an extension method like this:
var dc = new myDataContext();
Contract.Assume(dc.Cars!= null);
var cars = dc.Cars.WithOwner('Jim');
public static IQueryable<Car> WithOwner(this IQueryable<Car> cars, string owner)
{
Contract.Requires(cars != null);
return cars.Where(c => c.Owner == owner);
}
I get the following warning:
warning : CodeContracts: requires unproven: source != null
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我的猜测是,您的警告是由车主参数引起的,而不是由汽车引起的。在WithOwner方法中添加一个前提条件来检查owner是否不为null。
在您的第一个代码示例中,您对“Jim”进行了硬编码,因此没有问题,因为没有任何东西可以为空。
在第二个示例中,您创建了一个方法,静态编译器无法证明源(所有者)“永远不会为空”,因为其他代码可能会使用无效值来调用它。
My guess is that your warning is caused by the owner parameter, rather than the cars. Add a precondition in the WithOwner method to check if owner is not null.
In your first code sample, you have 'Jim' hard-coded, so no problems there because there is not something which can be null.
In your second example you created a method for which the static compiler cannot prove that the source ( being owner ) 'will never be null', as other code might call it with an invalid values.
我想知道如何使用扩展方法编译代码,因为您在方法签名中缺少
this
关键字。/KP
I wonder how you get the code compiled with the Extension method since you are missing
this
keyword in your method signature./KP
您的代码片段可能没有完全描述您正在使用的代码。
考虑这个片段:
在这个片段中,运行时可能会抱怨您提到的警告,但它并不是抱怨
Cars
可能为空,而是抱怨WithOwner< 的结果/code>(传递到
Select
)可能为空。您可以通过确保扩展方法的结果不为 null 来满足运行时的要求:
此约定应该没问题,因为
Where
不会返回 null,而是返回一个Enumerable.Empty;()
当没有匹配项时。Its possible that your code snippet does not completely describe the code you are using.
Consider this snippet instead:
In this snipped its likely the runtime will complain with the warning you mentioned, but it is not complaining about
Cars
possibly being null, it is complaining about the result fromWithOwner
(passed intoSelect
) possibly being null.You can satisfy the runtime by ensuring that the result from your extension method will not be null:
This contract should be ok because
Where
will not return null, but instead returns anEnumerable.Empty<T>()
when there are no matches.我们在几个版本之前修复了这个问题。该警告是由于缺少有关 Linq 表达式构造等的一些约定。Linq 表达式方法具有约定,并且 C# 编译器生成调用这些方法的代码。如果我们在被调用的方法上没有足够的后置条件,那么您可能会收到这些关于您甚至不知道其存在的代码的神秘警告(除非您使用 ILdasm 查看)。
We fixed this a few releases back. The warning was due to some missing contracts around Linq expression construction etc. Linq expression methods have contracts and the C# compiler generates code that calls these methods. If we don't have enough post conditions on the called methods, then you can get these cryptic warnings about code that you don't even know is there (unless you look with ILdasm).