Кодовые контракты в C# 4.0
Я сделал такой метод
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;
}
}
Теперь вызывающий код должен правильно обрабатывать нулевое значение. Есть ли способ выразить контракт для всех вызывающих абонентов, чтобы они могли обрабатывать нулевое значение, возвращаемое этим методом?
PersonCollection pc = new PersonCollection();
IPerson p = pc.GetPerson(anyId);
p.Name = "Hugo"; // here I want to have a curly line
То, что я хочу, это то, что р отмечен как потенциально проблемный.
РЕДАКТИРОВАТЬ Я просто изменил код и добавил вызывающий код и поведение expcected. Также я добавил атрибут, который, вероятно, не существует в методе GetPerson
2 ответа
То, что вы хотите (после прочтения комментариев), произойдет по умолчанию:
Если вы включите кодовые контракты в вызывающем коде, верификатор будет считать, что возврат GetPerson()
может быть нулевым Так:
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
}
И, совершенно не относящийся к этому вопросу, это обычно будет более эффективным, если люди (как) словарь:
IPerson GetPerson(Guid personId)
{
Person p = null;
this.persons.TryGetValue(personId, out p);
return p;
}
Кодекс контракта не предоставляет такой возможности, как и C#
Кодовые контракты требуют только от вызывающей стороны соблюдать определенные ограничения в начале вызываемого метода. Это так называемые предварительные условия. Постусловия являются обязанностью вызываемого и определяют состояние программы при выходе из вызываемого метода.
Проектирование по контракту - это способ определить эти обязанности, а не сообщать вызывающим лицам, как они должны справляться с определенными условиями, вызванными вызываемым методом.