4

I made a method like this

class PersonCollection
{
  [Contracts.CanReturnNull]  //dont know if something like this exists?
  IPerson GetPerson(Guid personId)
  {
       if (this.persons.Contains(personId))
            return this.persons[personId];
       else
            return null;
  }
}

Now the calling code needs to handle the null value properly. Is there a way to express a contract for all callers that they need to be able to handle the null value returned by this method?

PersonCollection pc = new PersonCollection();
IPerson p = pc.GetPerson(anyId);
p.Name = "Hugo";  // here I want to have a curly line

What I want is that the p gets marked as potential problematic.

EDIT I just modified the code and added the calling code and the expcected behaviour. Also I added an attribute that probalbly does not exists on the method GetPerson

schoetbi
  • 12,009
  • 10
  • 54
  • 72
  • In C# reference-type variables have `null` as the default value. Unless `GetPerson` ensures by contract that `IPerson` is not null, the caller must deal with the possibility of a `null` return. – Peter K. Jun 08 '11 at 14:07
  • I'd recommend changing your method name to GetPersonOrNull, if you want to make it clear to the caller that he might get a null value. – koenmetsu Jun 08 '11 at 14:34

2 Answers2

2

Code Contract does not provide such a feature, nor does C#

Code Contracts only requires from the caller to comply to certain constraints at the start of the called method. These are the so-called preconditions. The postconditions are the responsibility of the callee, and defines what the state of the program will be on exit of the called method.

Design by Contract is a way to define these responsibilities, not to tell callers how they should handle certain conditions caused by the called method.

koenmetsu
  • 1,044
  • 9
  • 31
  • 2
    +1: Code Contracts let you say "this parameter cannot be null" as a pre-condition or "this return value will not be null" as a post-condition. – Peter K. Jun 08 '11 at 14:02
1

What you seem to want (after reading the comments) will happen by default:

If you enable Code Contracts in the calling code, the verifier will consider that the return of GetPerson() can be null. So:

IPerson GetPerson(Guid personId)
{
   // no pre/post conditions
}

void PrintPerson(IPerson p)
{
   Contract.Requires(p != null);
   ...
}

void Foo()
{
     var p = GetPerson(id);
     PrintPerson(p);    // a warning here: can not verify p != null
}

And, totally irrelevant to the question, this will usually be more efficient if persons is (like) a Dictionary:

IPerson GetPerson(Guid personId)
{
   Person p = null;

   this.persons.TryGetValue(personId, out p);
   return p;
}
H H
  • 263,252
  • 30
  • 330
  • 514
  • I just extended my question with my expected behaviour. Actually I like to mark the Method GetPerson with something like an attribute saying that the caller needs to be able to handle a null return value. – schoetbi Jun 09 '11 at 09:08
  • @schoet, I got that, the point is that you get exactly that result by doing _nothing_. GetPerson() without a PostCondition is already saying "I could return null" – H H Jun 09 '11 at 09:14
  • > Its working now I installed the version without static checking. Thanks! – schoetbi Jun 09 '11 at 10:02