Search code examples
c#code-contractsbuilder-pattern

C# Code Contracts with Builder Pattern - "Possibly calling a method on a null reference"


I'm investigating Code Contracts and I'm implementing the Builder Pattern like this:

public class PersonCaution
{
    private PersonCaution()
    {
    }

    public string CautionType { get; private set; }
    public string Remarks { get; private set; }

    public class Builder
    {
        private string _cautionType;
        private string _remarks;

        public Builder WithCautionType(string value)
        {
            Contract.Ensures(Contract.Result<Builder>() != null);

            _cautionType = value;                
            return this;
        }

        public Builder WithRemarks(string value)
        {
            Contract.Ensures(Contract.Result<Builder>() != null);

            _remarks = value;
            return this;
        }

        public PersonCaution Build()
        {
            Contract.Ensures(Contract.Result<PersonCaution>() != null);

            return new PersonCaution
            {
                CautionType = _cautionType,
                Remarks = _remarks
            };
        }
    }
}

Here's a snippet showing how I use the Builder class:

if (row != null)
{
    var builder = new PersonCaution.Builder()
        .WithCautionType((string)row.Element("PersonCaution__Type1G"))
        .WithRemarks((string)row.Element("PersonCaution__Remarks"));

    if (builder != null)
    {
        personCautions.Add(builder.Build());
    }
}

However, the Code Contracts static checker fails with this error:

Possibly calling a method on a null reference. Do you expect that NWP.PointServices.Domain.Model.People.PersonCaution+Builder.WithCautionType(System.String) returns non-null?

Q. I thought that the Contract.Ensures postcondition would satisfy the static checker, but it doesn't. What do I need to do to remove the error? Thanks v much.

Note. I only see the issue if the Builder class is in a separate Project to the code which calls it.

More info:

  • Visual Studio Professional 2015 14.0.25424.00 Update 3
  • All projects target .Net 4.6.1
  • Code Contracts installed via Visual Studio Extension, v 1.8
  • I'm successfully using Code Contracts in other (non Builder) areas of the project

Solution

  • As we have found out, all you need is to enable build for contract references from CC project tab to enable cross-project analysis ("Contract Reference Assembly" = "Build")