-
Notifications
You must be signed in to change notification settings - Fork 12
Add Contract
Note
Adding code contracts is not suggested anymore when nullable reference types (C# 8.0 or higher) are enabled.
Context action | When suggested |
---|---|
Add contract: x ≠ null * |
x is nullable |
Add contract: x.Count > 0
|
x is ICollection<T>
|
Add contract: x.All(item => item ≠ null) ** |
x is ICollection<T> and T is nullable |
Add contract: x.All(pair => pair.Value ≠ null)
|
x is IDictionary<TKey,TValue> and TValue is nullable |
Add contract: !string.IsNullOrEmpty(x) * |
x is string
|
Add contract: x = enum.X || x = enum.Y…
|
x is enum |
Add contract: x ≥ enum.X && x ≤ enum.Y
|
x is enum and enum is gapless |
Add contract: x ≥ flags.None && x ≤ (flags.X | flags.Y…)
|
x is flagged enum and is gapless |
Add contract: x > 0
|
x is number |
Add contract: x = 0
|
x is number |
Add contract: x ≥ 0
|
x is number (signed) |
Add contract: x ≠ 0
|
x is number (signed) |
Add contract: x < 0
|
x is number (signed) |
Add contract: x ≤ 0
|
x is number (signed) |
Add contract: x ≠ Guid.Empty
|
x is Guid
|
Add contract: x.TimeOfDay ≠ TimeSpan.Zero
|
x is DateTime
|
Add contract: x > TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x = TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x ≥ TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x ≠ TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x < TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x ≤ TimeSpan.Zero
|
x is TimeSpan
|
Add contract: x = (U)IntPtr.Zero
|
x is IntPtr or UIntPtr
|
Add contract: x ≠ (U)IntPtr.Zero
|
x is IntPtr or UIntPtr
|
* The [NotNull]
annotation is also applied
** The [ItemNotNull]
annotation is also applied
If suggested on | Applied |
---|---|
non-static fields | in the object invariant method* |
non-auto properties | as preconditions for setters and post-conditions for getters |
non-static auto properties | in the object invariant method* |
indexers | as preconditions for setters and post-conditions for getters |
methods | as post-conditions for return values |
parameters | as preconditions for input and ref parameters and post-conditions for ref and out parameters |
* The object invariant method is created if missing.
The contracts are added to the contract class. The contract class and corresponding annotations (both ways) are added if missing.
- Expression-bodied methods (incl. the "contact invariant" methods);
- expression-bodied constructors;
- expression-bodied operators;
- expression-bodied properties (and indexers);
- properties (and indexers) with expression-bodied getters and setters;
are currently not supported.
Workaround: manually convert the member to use the statement body.
Local functions are currently not supported.
Adding a contract to a member of a generic abstract class or a generic interface adds the incorrect [ContractClass(typeof(MyGenericClassContract))]
annotation (the correct annotation is [ContractClass(typeof(MyGenericClassContract<,*>))]
).
* depends on amount of generic parameters: <> for one generic parameter, <,> for two, <,,> for three, and so on.
Workaround: manually fix the incorrectly generated code.