Контракты с несколькими аргументами

Я начал кодировать с контрактами в C#. Я хочу выразить следующее свойство в C#

ISet<Tuple<A,B>> set;
Contract.Requires(!Contract.Exists(set, (e1,e2) => (((e1 != null) && (e2 != null)) &&    (e1.Item1 == e2.Item1) && (e1.Item2 != e2.Item2))));

т.е. если первые элементы двух кортежей одинаковы, второй должен быть одинаковым.

Проблема в том, что (e1,e2) => ... не является допустимым выражением из-за двух аргументов. Кто-нибудь сейчас, как выразить этот контракт с e1 и e2? Или как это переписать?

2 ответа

Решение

Спасибо за разъяснения с шаблоном. Я хотел сказать следующее:

\ forall s, t в ISet>: (sa == ta) -> (sb==tb)

Я думаю, это было как-то неясно. Я наконец решил это следующим образом (ранее не зная, что возможно вложить Contract.Exist и Contract.ForAll и после некоторой логической переформулировки)

ISet<Tuple<A,B> set;
Contract.Invariant(Contract.ForAll(set, s => s != null && Contract.ForAll(set, t => t != null && ((s.Item1 != t.Item1)||(s.Item2 == t.Item2)))));

Шаблонный аргумент Contract.Exist() это элемент коллекции, так что в вашем случае Tuple<A, B>, Вы не можете отделить их (A а также B от Tuple<A, B> потому что для ISet<T> шаблон T является Tuple<A, B>).

Перепишите это как (если я понял, что вы требуете, чтобы элементы кортежа не были равны, и они не nullна всякий случай просто поменяй)

Contract.Requires(!Contract.Exists(set,
    x => x.Item1 == null || x.Item2 == null || x.Item1 == x.Item2));
Другие вопросы по тегам