.net-4.0 - unanimité - vote copropriété



Contrats de code-Supposer vs Nécessite (2)

Quelle est la différence entre ces deux déclarations?

Contract.Requires(string.IsNullOrWhiteSpace(userName));

Contract.Assume(string.IsNullOrWhiteSpace(userName));

https://src-bin.com


Answer #1

Il diffère seulement de la conception-temps / statique-analyse-temps

Contract.Assume: "Indique aux outils d'analyse de code de supposer que la condition spécifiée est vraie, même si elle ne peut pas toujours être vérifiée statiquement" Et: Lors de l'exécution, l'utilisation de cette méthode équivaut à la méthode Assert (Boolean).

Contract.Requires garantit que le prédicat donné est vrai et que les analyseurs de code statiques peuvent générer une erreur s'ils ne peuvent pas "prouver" que ce n'est pas le cas. Sur Contract.Assume l'analyseur statique continuera / émettre un avertissement / tout ce que l'outil décidera.


Answer #2

Imaginez que vous avez une méthode comme celle-ci:

bool ContainsAnX(string s)
{
    return s.Contains("X");
}

Maintenant, cette méthode échouera toujours si vous lui passez null , donc vous voulez vous assurer que cela n'arrive jamais. C'est ce que Contract.Requires est pour. Il définit une condition préalable pour la méthode, qui doit être true pour que la méthode s'exécute correctement. Dans ce cas, nous aurions:

bool ContainsAnX(string s)
{
    Contract.Requires(s != null);

    return s.Contains("X");
}   

( Note : Requires et Ensures doit toujours être au début d'une méthode, car ce sont des informations sur la méthode dans son ensemble, Assume soit utilisée dans le code lui-même, car ce sont des informations sur ce point dans le code.)

Maintenant, dans votre code qui appelle la méthode "ContainsAnX", vous devez vous assurer que la chaîne n'est pas nulle. Votre méthode pourrait ressembler à ceci:

void DoSomething()
{
    var example = "hello world";

    if (ContainsAnX(example))
        Console.WriteLine("The string contains an 'X'.");
    else
        Console.WriteLine("The string does not contain an 'X'.");
}

Cela fonctionnera correctement, et le vérificateur statique peut prouver que l' example n'est pas nul.

Cependant, vous pourriez faire appel à des bibliothèques externes, qui n'ont aucune information sur les valeurs qu'elles renvoient (c'est-à-dire qu'elles n'utilisent pas les contrats de code). Changeons l'exemple:

void DoSomething()
{
    var example = OtherLibrary.FetchString();

    if (ContainsAnX(example))
        Console.WriteLine("The string contains an 'X'.");
    else
        Console.WriteLine("The string does not contain an 'X'.");
}

Si OtherLibrary n'utilise pas les contrats de code, le vérificateur statique se plaindra que l' example peut être nul.

Peut-être que leur documentation pour la bibliothèque dit que la méthode ne retournera jamais null (ou ne devrait jamais!). Dans ce cas, nous en savons plus que le vérificateur statique, nous pouvons donc lui dire de Assume que la variable ne sera jamais nulle:

void DoSomething()
{
    var example = OtherLibrary.FetchString();

    Contract.Assume(example != null);

    if (ContainsAnX(example))
        Console.WriteLine("The string contains an 'X'.");
    else
        Console.WriteLine("The string does not contain an 'X'.");
}

Maintenant ce sera correct avec le vérificateur statique. Si vous avez des contrats d'exécution activés, l'hypothèse sera également vérifiée lors de l'exécution.

Un autre cas où vous pourriez avoir besoin de Supposer est quand vos conditions préalables sont très complexes et le vérificateur statique a du mal à les prouver. Dans ce cas, vous pouvez lui donner un coup de pouce pour l'aider :)

En termes de comportement d'exécution, il n'y aura pas beaucoup de différence entre l'utilisation de Suppose et Nécessite. Cependant, les résultats avec le vérificateur statique seront très différents. La signification de chacun est également différente, en termes de qui est responsable de l'erreur en cas d'échec:

  • Nécessite que le code qui appelle cette méthode doit s'assurer que la condition est respectée.
  • Supposons que cette méthode fasse une supposition qui devrait toujours être vraie.




code-contracts