使用Code Contracts和Linq To Sql时如何避免"source!= null"?

Ran*_*mer 6 code-contracts 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();
Run Code Online (Sandbox Code Playgroud)

但是当我将过滤器转换为这样的扩展方法时:

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);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下警告:

警告:CodeContracts:需要unproven:source!= null

koe*_*tsu 1

我的猜测是,您的警告是由车主参数引起的,而不是由汽车引起的。在WithOwner方法中添加一个前提条件来检查owner是否不为null。

public static IQueryable<Car> WithOwner(IQueryable<Car> cars, string owner)
{
    Contract.Requires(cars != null);
    Contract.Requires(!string.isNullOrEmpty(owner));
    return cars.Where(c => c.Owner = owner);
}
Run Code Online (Sandbox Code Playgroud)

在您的第一个代码示例中,您对“Jim”进行了硬编码,因此没有问题,因为没有任何东西可以为空。

在第二个示例中,您创建了一个方法,静态编译器无法证明源(所有者)“永远不会为空”,因为其他代码可能会使用无效值来调用它。