Note that there are some explanatory texts on larger screens.

plurals
  1. POCustom Methods in Contract.Ensures
    primarykey
    data
    text
    <p>I'm trying to understand Code Contracts in a bit more detail. I've got the following contrived example, where I'm trying to assert the invariant of a try/get pattern that if it returns <code>true</code> then the <code>out</code> object is non-null, otherwise if it returns <code>false</code>.</p> <pre><code> public static bool TryParseFruit(string maybeFruit, out Fruit fruit) { Contract.Requires(maybeFruit != null); Contract.Ensures((Contract.Result&lt;bool&gt;() &amp;&amp; Contract.ValueAtReturn(out fruit) != null) || (!Contract.Result&lt;bool&gt;() &amp;&amp; Contract.ValueAtReturn(out fruit) == null)); // Elided for brevity if (ICanParseIt()) { fruit = SomeNonNullValue; return true; } else { fruit = null; return false; } } </code></pre> <p>I don't like the duplication inside <code>Contract.Ensures</code> so I wanted to factor out my own method for this.</p> <pre><code>[Pure] public static bool Implies(bool a, bool b) { return (a &amp;&amp; b) || (!a &amp;&amp; !b); } </code></pre> <p>Then I changed my invariant in <code>TryParseFruit</code> to</p> <pre><code>Contract.Ensures(Implies(Contract.Result&lt;bool&gt;(), Contract.ValueAtReturn(out fruit) != null); </code></pre> <p>But this generates warnings that the "ensures is unproven". If I then perform the inline refactoring on my <code>Implies</code> method then everything is OK again.</p> <p>Could someone explain to me why this happens? I'm guessing it's because <code>Contract.ValueAtReturn</code> is used magically in some way that means I can't just pass it's result off to another function and expect it to work.</p> <p>(Update #1)</p> <p>I think that all of the following <code>Contract.Ensures</code> express the same thing (namely that if the function returns <code>true</code> then <code>fruit</code> is non-null, otherwise <code>fruit</code> is <code>null</code>). Note that I am only using one of these at a time :)</p> <pre><code>Contract.Ensures(Implies(Contract.Result&lt;bool&gt;(), Contract.ValueAtReturn(out fruit) != null)); Contract.Ensures(Contract.Result&lt;bool&gt;() == (Contract.ValueAtReturn(out fruit) != null)); Contract.Ensures(Contract.Result&lt;bool&gt;() ^ (Contract.ValueAtReturn(out fruit) == null)); </code></pre> <p>However, none of the above <code>Contract.Ensures</code> lead to a clean compile of the code below. I want the Code.Contracts to express that <code>fruit.Name</code> cannot be a null reference.</p> <pre><code> Fruit fruit; while (!TryGetExample.TryParseFruit(ReadLine(), out fruit)) { Console.WriteLine("Try again..."); } Console.WriteLine(fruit.Name); </code></pre> <p>I am only able to get the completely clean compile with code contracts if I use the long winded way of expressing this detailed above. My question is why!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload