Search Unity

Question Code contracts support

Discussion in 'Scripting' started by Efril, Jul 22, 2020.

  1. Efril

    Efril

    Joined:
    Aug 31, 2013
    Posts:
    82
    Hello all. I found that .NET code contracts works weird in Unity. I have a simple scenario where I need to check that parameters of a class constructor not null and the code contracts seem to be the most obvious and straightforward way to do this.
    Code (CSharp):
    1.     class ContractsTest
    2.     {
    3.         private readonly string _value;
    4.  
    5.         public ContractsTest(string Value)
    6.         {
    7.             _value = Value;
    8.         }
    9.     }
    10.  
    11.     void Start()
    12.     {
    13.         new ContractsTest(null);
    14.     }
    Since Unity currently supports .NET 4.x I assumed that code contracts supported as well. But the following version of constructor not throwing any exceptions:
    Code (CSharp):
    1.         public ContractsTest(string Value)
    2.         {
    3.             Contract.Requires(Value != null);
    4.             _value = Value;
    5.         }
    And the following:
    Code (CSharp):
    1.         public ContractsTest(string Value)
    2.         {
    3.             Contract.Requires<NullReferenceException>(Value != null);
    4.             _value = Value;
    5.         }
    Throws the exception regardless the parameter passed to the constructor:
    And the following:
    Code (CSharp):
    1.         public ContractsTest(string Value)
    2.         {
    3.             Contract.Assume(Value != null);
    4.             _value = Value;
    5.         }
    works exactly as expected:
    So why I can't rely on code contracts in my code? Maybe there are some magic project settings exist that will make them work?
    Thanks in advance.
     
  2. RGV

    RGV

    Joined:
    Jan 25, 2016
    Posts:
    48
    This is quite interesting to us.
    Got the same point, besides neither invariants work at all.
     
  3. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,066
    Code Contracts seems to rely on a separate binary to rewrite the assemblies and a Visual Studio plugin to run this binary. Since Unity uses its own compilation pipeline, the rewriter is never run on the built assemblies.

    It also seems Code Contracts has been discontinued? The last release has been over seven years ago and the GitHub repository is archived. I couldn't find an existing Unity integration and, given the state of the project, it's highly unlikely that there ever will be one. Unity does want to switch to using the standard .Net compilation pipeline, at which point libraries like these should work directly in Unity, but this would also require Code Contracts to be updated for modern .Net, which doesn't seem likely to happen.

    You're probably better off using Unity's assertion library, even if that doesn't cover the full functionality of Code Contracts, or find a library that has explicit support for Unity.
     
    RGV likes this.
  4. RGV

    RGV

    Joined:
    Jan 25, 2016
    Posts:
    48
    I ended up using my own library, which uses the UNITY_ASSERTIONS conditional when evaluating preconditions, postconditions and invariants.
    The only reason to not use Unity's class Assert is the lack of semantic richness, imho.