Вот простой метод манипуляции графами, который я украсил кодовыми контрактами.Пример неудачных примеров контрактов Graph.Remove (Edge e)
Гарантии претензии не подтвердятся, но я не понимаю, почему! Я считаю, что он утверждает, что после вызова Remove() либо край больше не находится в списке ребер, либо результат равен false. Он не утверждает ничего о состоянии графика, если результат верен. Статическому контролеру это не нравится, и я не получил Pex, чтобы сказать мне, как (хотя я, вероятно, просто не знаю, как его использовать).
Замок посторонний для этого примера, я считаю, но я оставлю его на всякий случай. Кроме того, у делегата для OnRemoveEdge нет гарантий, но я неявно предполагаю, что он не будет повторно включен в код Graph. Кроме того, Успение есть после него.
public bool Remove(E edge)
{
Contract.Requires(edge != null);
Contract.Ensures(!Contract.Exists(edges, e => e == edge) || !Contract.Result<bool>());
lock (sync)
{
if (!OnBeforeRemoveEdge(edge)) return false;
if (!edges.Remove(edge)) return false;
}
OnRemoveEdge(edge);
Contract.Assume(!Contract.Exists(edges, e => e == edge));
return true;
}
Обновление: Я изменил код, чтобы переместить обработчик событий, OnRemoveEdge(), (но не делегат, OnBeforeRemoveEdge) из замка. Но тогда, что это делает для предположения контракта, связанного с потоками? Имеет ли код Контракты однопоточную модель? Хммм.
В настоящее время кодовые контракты предполагают однопоточную модель. – porges
Является ли «краем» список? 'List.Remove' не имеет никаких контрактов. – porges
@Porges - Спасибо, что ответили. Разве это не означает, что предположение о нехватке контрактов в списке? –