3

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
Howard
  • 694
  • 5
  • 21
  • Well, I'm on Update 3 and Code Contracts not only checked everything ok but also gave me a warning that (builder!=null) evaluation is redundant 'cause builder is always not null. It seems I can't help you on this one. – Sergey.quixoticaxis.Ivanov Jul 25 '16 at 16:09
  • @Sergey.quixoticaxis.Ivanov - thanks. I added a note above that I only see the issue if the Builder class is in a separate Project to the code which calls it. The Code Contract settings are the same for each project. – Howard Jul 27 '16 at 07:13
  • Hello once again. I moved Builder class to another dll and it still works fine for me :-/ Just in case, did you enable Contract Reference Assembly = Build for the assembly with the definition of Builder class? – Sergey.quixoticaxis.Ivanov Jul 27 '16 at 12:54
  • The problem is caused when 2 things are true: The Builder and calling code are in separate projects. Both projects have static and run-time checking enabled. I'll investigate further to see what other settings may need to be set to resolve this. – Howard Jul 28 '16 at 07:17
  • @Sergey.quixoticaxis.Ivanov. Setting "Contract Reference Assembly" = "Build" for the assembly with the definition of Builder class fixed the issue. You can add an answer for that if you like? However all my projects had set this to "DoNotBuild", so why did some pre-conditions (in other projects) pass? – Howard Jul 28 '16 at 07:56
  • I undeleted my answer) I can't check it right now (away from PC with VS) but my guess would be about inference of conditions. You may have "infer ensures" turned on. – Sergey.quixoticaxis.Ivanov Jul 28 '16 at 12:07

1 Answers1

1

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")