How to avoid "source! = Null" when using Code Contracts and Linq To Sql?

I have the following code using a regular data context that works fine:

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 as follows:

 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

+6
linq-to-sql code-contracts
source share
4 answers

I assume that your warning is caused by the owner parameter, not by the machines. Add the precondition to the WithOwner method to check if the owner is invalid.

 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); } 

In your first code example, you have "Jim" with hard coding, so there is no problem because there is nothing that can be null.

In your second example, you created a method for which the static compiler cannot prove that the source (the owner) "will never be empty," because other code may call it with invalid values.

+1
source share

I wonder how you get the code compiled using the extension method, since this keyword is missing from your method signature.

 public static IQueryable<Car> WithOwner(this IQueryable<Car> cars, string owner) { ... } 

/ Kp

0
source share

Your code fragment may not fully describe the code you are using.

Instead, consider this snippet:

 var dc = new myDataContext(); Contract.Assume(dc.Cars!= null); var models = dc.Cars.WithOwner('Jim').Select(c => c.Model); public static IQueryable<Car> WithOwner(this IQueryable<Car> cars, string owner) { Contract.Requires(cars != null); return cars.Where(c => c.Owner == owner); } 

In this case, the runtime will probably complain about the warning you mentioned, but it does not complain that Cars may be empty, it complains about the result from WithOwner (passed to Select ), possibly zero.

You can satisfy the runtime by ensuring that the result of your extension method is not zero:

 Contract.Ensures(Contract.Result<IQueryable<Car>>() != null); 

This contract must be approved because Where does not return null, but instead returns Enumerable.Empty<T>() when there are no matches.

0
source share

We fixed this a few issues ago. The warning was triggered by some missing contracts around the construction of the Linq expression, etc. Linq expression methods have contracts, and the C # compiler generates code that calls these methods. If we do not have sufficient reporting conditions for the called methods, you may receive these cryptic warnings about code that you do not even know if (if you are not looking with ILdasm).

0
source share

All Articles