我开始使用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)=&gt;由于这两个参数,...不是有效的表达式。现在有人如何用e1和e2表达这个合同?或者如何重写它?
答案 0 :(得分:2)
感谢您对模板的澄清。我想说的是:
\ forall s,t in ISet&lt;元组&LT; A,B&gt;&gt; :( s.a == t.a) - &gt; (S.B == t.b)
我想这有点不清楚。我终于通过以下方式解决了它(之前不知道可以嵌套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)))));
答案 1 :(得分:1)
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));