1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 /*============================================================
9 ** Purpose: The contract class allows for expressing preconditions,
10 ** postconditions, and object invariants about methods in source
11 ** code for runtime checking & static analysis.
13 ** Two classes (Contract and ContractHelper) are split into partial classes
14 ** in order to share the public front for multiple platforms (this file)
15 ** while providing separate implementation details for each platform.
17 ===========================================================*/
18 #define DEBUG // The behavior of this contract library should be consistent regardless of build type.
20 using System
.Collections
.Generic
;
21 using System
.Diagnostics
.CodeAnalysis
;
22 using System
.Reflection
;
24 namespace System
.Diagnostics
.Contracts
29 /// Methods and classes marked with this attribute can be used within calls to Contract methods. Such methods not make any visible state changes.
31 [Conditional("CONTRACTS_FULL")]
32 [AttributeUsage(AttributeTargets
.Constructor
| AttributeTargets
.Method
| AttributeTargets
.Property
| AttributeTargets
.Event
| AttributeTargets
.Delegate
| AttributeTargets
.Class
| AttributeTargets
.Parameter
, AllowMultiple
= false, Inherited
= true)]
33 public sealed class PureAttribute
: Attribute
38 /// Types marked with this attribute specify that a separate type contains the contracts for this type.
40 [Conditional("CONTRACTS_FULL")]
41 [Conditional("DEBUG")]
42 [AttributeUsage(AttributeTargets
.Class
| AttributeTargets
.Interface
| AttributeTargets
.Delegate
, AllowMultiple
= false, Inherited
= false)]
43 public sealed class ContractClassAttribute
: Attribute
45 private Type _typeWithContracts
;
47 public ContractClassAttribute(Type typeContainingContracts
)
49 _typeWithContracts
= typeContainingContracts
;
52 public Type TypeContainingContracts
54 get { return _typeWithContracts; }
59 /// Types marked with this attribute specify that they are a contract for the type that is the argument of the constructor.
61 [Conditional("CONTRACTS_FULL")]
62 [AttributeUsage(AttributeTargets
.Class
, AllowMultiple
= false, Inherited
= false)]
63 public sealed class ContractClassForAttribute
: Attribute
65 private Type _typeIAmAContractFor
;
67 public ContractClassForAttribute(Type typeContractsAreFor
)
69 _typeIAmAContractFor
= typeContractsAreFor
;
72 public Type TypeContractsAreFor
74 get { return _typeIAmAContractFor; }
79 /// This attribute is used to mark a method as being the invariant
80 /// method for a class. The method can have any name, but it must
81 /// return "void" and take no parameters. The body of the method
82 /// must consist solely of one or more calls to the method
83 /// Contract.Invariant. A suggested name for the method is
84 /// "ObjectInvariant".
86 [Conditional("CONTRACTS_FULL")]
87 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false, Inherited
= false)]
88 public sealed class ContractInvariantMethodAttribute
: Attribute
93 /// Attribute that specifies that an assembly is a reference assembly with contracts.
95 [AttributeUsage(AttributeTargets
.Assembly
)]
96 public sealed class ContractReferenceAssemblyAttribute
: Attribute
101 /// Methods (and properties) marked with this attribute can be used within calls to Contract methods, but have no runtime behavior associated with them.
103 [Conditional("CONTRACTS_FULL")]
104 [AttributeUsage(AttributeTargets
.Method
| AttributeTargets
.Property
, AllowMultiple
= false, Inherited
= true)]
105 public sealed class ContractRuntimeIgnoredAttribute
: Attribute
110 /// Instructs downstream tools whether to assume the correctness of this assembly, type or member without performing any verification or not.
111 /// Can use [ContractVerification(false)] to explicitly mark assembly, type or member as one to *not* have verification performed on it.
112 /// Most specific element found (member, type, then assembly) takes precedence.
113 /// (That is useful if downstream tools allow a user to decide which polarity is the default, unmarked case.)
116 /// Apply this attribute to a type to apply to all members of the type, including nested types.
117 /// Apply this attribute to an assembly to apply to all types and members of the assembly.
118 /// Apply this attribute to a property to apply to both the getter and setter.
120 [Conditional("CONTRACTS_FULL")]
121 [AttributeUsage(AttributeTargets
.Assembly
| AttributeTargets
.Class
| AttributeTargets
.Struct
| AttributeTargets
.Method
| AttributeTargets
.Constructor
| AttributeTargets
.Property
)]
122 public sealed class ContractVerificationAttribute
: Attribute
126 public ContractVerificationAttribute(bool value) { _value = value; }
130 get { return _value; }
135 /// Allows a field f to be used in the method contracts for a method m when f has less visibility than m.
136 /// For instance, if the method is public, but the field is private.
138 [Conditional("CONTRACTS_FULL")]
139 [AttributeUsage(AttributeTargets
.Field
)]
140 public sealed class ContractPublicPropertyNameAttribute
: Attribute
142 private string _publicName
;
144 public ContractPublicPropertyNameAttribute(string name
)
151 get { return _publicName; }
156 /// Enables factoring legacy if-then-throw into separate methods for reuse and full control over
157 /// thrown exception and arguments
159 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false)]
160 [Conditional("CONTRACTS_FULL")]
161 public sealed class ContractArgumentValidatorAttribute
: Attribute
166 /// Enables writing abbreviations for contracts that get copied to other methods
168 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false)]
169 [Conditional("CONTRACTS_FULL")]
170 public sealed class ContractAbbreviatorAttribute
: Attribute
175 /// Allows setting contract and tool options at assembly, type, or method granularity.
177 [AttributeUsage(AttributeTargets
.All
, AllowMultiple
= true, Inherited
= false)]
178 [Conditional("CONTRACTS_FULL")]
179 public sealed class ContractOptionAttribute
: Attribute
181 private string _category
;
182 private string _setting
;
183 private bool _enabled
;
184 private string? _value
;
186 public ContractOptionAttribute(string category
, string setting
, bool enabled
)
188 _category
= category
;
193 public ContractOptionAttribute(string category
, string setting
, string value)
195 _category
= category
;
200 public string Category
202 get { return _category; }
205 public string Setting
207 get { return _setting; }
212 get { return _enabled; }
217 get { return _value; }
221 #endregion Attributes
224 /// Contains static methods for representing program contracts such as preconditions, postconditions, and invariants.
227 /// WARNING: A binary rewriter must be used to insert runtime enforcement of these contracts.
228 /// Otherwise some contracts like Ensures can only be checked statically and will not throw exceptions during runtime when contracts are violated.
229 /// Please note this class uses conditional compilation to help avoid easy mistakes. Defining the preprocessor
230 /// symbol CONTRACTS_PRECONDITIONS will include all preconditions expressed using Contract.Requires in your
231 /// build. The symbol CONTRACTS_FULL will include postconditions and object invariants, and requires the binary rewriter.
233 public static partial class Contract
240 /// Instructs code analysis tools to assume the expression <paramref name="condition"/> is true even if it can not be statically proven to always be true.
242 /// <param name="condition">Expression to assume will always be true.</param>
244 /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
247 [Conditional("DEBUG")]
248 [Conditional("CONTRACTS_FULL")]
249 public static void Assume([DoesNotReturnIf(false)] bool condition
)
253 ReportFailure(ContractFailureKind
.Assume
, null, null, null);
258 /// Instructs code analysis tools to assume the expression <paramref name="condition"/> is true even if it can not be statically proven to always be true.
260 /// <param name="condition">Expression to assume will always be true.</param>
261 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
263 /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
266 [Conditional("DEBUG")]
267 [Conditional("CONTRACTS_FULL")]
268 public static void Assume([DoesNotReturnIf(false)] bool condition
, string? userMessage
)
272 ReportFailure(ContractFailureKind
.Assume
, userMessage
, null, null);
281 /// In debug builds, perform a runtime check that <paramref name="condition"/> is true.
283 /// <param name="condition">Expression to check to always be true.</param>
285 [Conditional("DEBUG")]
286 [Conditional("CONTRACTS_FULL")]
287 public static void Assert([DoesNotReturnIf(false)] bool condition
)
290 ReportFailure(ContractFailureKind
.Assert
, null, null, null);
294 /// In debug builds, perform a runtime check that <paramref name="condition"/> is true.
296 /// <param name="condition">Expression to check to always be true.</param>
297 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
299 [Conditional("DEBUG")]
300 [Conditional("CONTRACTS_FULL")]
301 public static void Assert([DoesNotReturnIf(false)] bool condition
, string? userMessage
)
304 ReportFailure(ContractFailureKind
.Assert
, userMessage
, null, null);
312 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
314 /// <param name="condition">Boolean expression representing the contract.</param>
316 /// This call must happen at the beginning of a method or property before any other code.
317 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
318 /// Use this form when backward compatibility does not force you to throw a particular exception.
321 [Conditional("CONTRACTS_FULL")]
322 public static void Requires(bool condition
)
324 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires");
328 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
330 /// <param name="condition">Boolean expression representing the contract.</param>
331 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
333 /// This call must happen at the beginning of a method or property before any other code.
334 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
335 /// Use this form when backward compatibility does not force you to throw a particular exception.
338 [Conditional("CONTRACTS_FULL")]
339 public static void Requires(bool condition
, string? userMessage
)
341 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires");
345 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
347 /// <param name="condition">Boolean expression representing the contract.</param>
349 /// This call must happen at the beginning of a method or property before any other code.
350 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
351 /// Use this form when you want to throw a particular exception.
354 public static void Requires
<TException
>(bool condition
) where TException
: Exception
356 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires<TException>");
360 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
362 /// <param name="condition">Boolean expression representing the contract.</param>
363 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
365 /// This call must happen at the beginning of a method or property before any other code.
366 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
367 /// Use this form when you want to throw a particular exception.
370 public static void Requires
<TException
>(bool condition
, string? userMessage
) where TException
: Exception
372 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires<TException>");
380 /// Specifies a public contract such that the expression <paramref name="condition"/> will be true when the enclosing method or property returns normally.
382 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
384 /// This call must happen at the beginning of a method or property before any other code.
385 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
386 /// The contract rewriter must be used for runtime enforcement of this postcondition.
389 [Conditional("CONTRACTS_FULL")]
390 public static void Ensures(bool condition
)
392 AssertMustUseRewriter(ContractFailureKind
.Postcondition
, "Ensures");
396 /// Specifies a public contract such that the expression <paramref name="condition"/> will be true when the enclosing method or property returns normally.
398 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
399 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
401 /// This call must happen at the beginning of a method or property before any other code.
402 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
403 /// The contract rewriter must be used for runtime enforcement of this postcondition.
406 [Conditional("CONTRACTS_FULL")]
407 public static void Ensures(bool condition
, string? userMessage
)
409 AssertMustUseRewriter(ContractFailureKind
.Postcondition
, "Ensures");
413 /// Specifies a contract such that if an exception of type <typeparamref name="TException"/> is thrown then the expression <paramref name="condition"/> will be true when the enclosing method or property terminates abnormally.
415 /// <typeparam name="TException">Type of exception related to this postcondition.</typeparam>
416 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
418 /// This call must happen at the beginning of a method or property before any other code.
419 /// This contract is exposed to clients so must only reference types and members at least as visible as the enclosing method.
420 /// The contract rewriter must be used for runtime enforcement of this postcondition.
423 [Conditional("CONTRACTS_FULL")]
424 public static void EnsuresOnThrow
<TException
>(bool condition
) where TException
: Exception
426 AssertMustUseRewriter(ContractFailureKind
.PostconditionOnException
, "EnsuresOnThrow");
430 /// Specifies a contract such that if an exception of type <typeparamref name="TException"/> is thrown then the expression <paramref name="condition"/> will be true when the enclosing method or property terminates abnormally.
432 /// <typeparam name="TException">Type of exception related to this postcondition.</typeparam>
433 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
434 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
436 /// This call must happen at the beginning of a method or property before any other code.
437 /// This contract is exposed to clients so must only reference types and members at least as visible as the enclosing method.
438 /// The contract rewriter must be used for runtime enforcement of this postcondition.
441 [Conditional("CONTRACTS_FULL")]
442 public static void EnsuresOnThrow
<TException
>(bool condition
, string? userMessage
) where TException
: Exception
444 AssertMustUseRewriter(ContractFailureKind
.PostconditionOnException
, "EnsuresOnThrow");
447 #region Old, Result, and Out Parameters
450 /// Represents the result (a.k.a. return value) of a method or property.
452 /// <typeparam name="T">Type of return value of the enclosing method or property.</typeparam>
453 /// <returns>Return value of the enclosing method or property.</returns>
455 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
458 public static T Result
<T
>() { return default!; }
461 /// Represents the final (output) value of an out parameter when returning from a method.
463 /// <typeparam name="T">Type of the out parameter.</typeparam>
464 /// <param name="value">The out parameter.</param>
465 /// <returns>The output value of the out parameter.</returns>
467 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
470 public static T ValueAtReturn
<T
>(out T
value) { value = default!; return value; }
473 /// Represents the value of <paramref name="value"/> as it was at the start of the method or property.
475 /// <typeparam name="T">Type of <paramref name="value"/>. This can be inferred.</typeparam>
476 /// <param name="value">Value to represent. This must be a field or parameter.</param>
477 /// <returns>Value of <paramref name="value"/> at the start of the method or property.</returns>
479 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
482 public static T OldValue
<T
>(T
value) { return default!; }
484 #endregion Old, Result, and Out Parameters
491 /// Specifies a contract such that the expression <paramref name="condition"/> will be true after every method or property on the enclosing class.
493 /// <param name="condition">Boolean expression representing the contract.</param>
495 /// This contact can only be specified in a dedicated invariant method declared on a class.
496 /// This contract is not exposed to clients so may reference members less visible as the enclosing method.
497 /// The contract rewriter must be used for runtime enforcement of this invariant.
500 [Conditional("CONTRACTS_FULL")]
501 public static void Invariant(bool condition
)
503 AssertMustUseRewriter(ContractFailureKind
.Invariant
, "Invariant");
507 /// Specifies a contract such that the expression <paramref name="condition"/> will be true after every method or property on the enclosing class.
509 /// <param name="condition">Boolean expression representing the contract.</param>
510 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
512 /// This contact can only be specified in a dedicated invariant method declared on a class.
513 /// This contract is not exposed to clients so may reference members less visible as the enclosing method.
514 /// The contract rewriter must be used for runtime enforcement of this invariant.
517 [Conditional("CONTRACTS_FULL")]
518 public static void Invariant(bool condition
, string? userMessage
)
520 AssertMustUseRewriter(ContractFailureKind
.Invariant
, "Invariant");
530 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
531 /// for all integers starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.
533 /// <param name="fromInclusive">First integer to pass to <paramref name="predicate"/>.</param>
534 /// <param name="toExclusive">One greater than the last integer to pass to <paramref name="predicate"/>.</param>
535 /// <param name="predicate">Function that is evaluated from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</param>
536 /// <returns><c>true</c> if <paramref name="predicate"/> returns <c>true</c> for all integers
537 /// starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</returns>
538 /// <seealso cref="System.Collections.Generic.List<T>.TrueForAll"/>
540 public static bool ForAll(int fromInclusive
, int toExclusive
, Predicate
<int> predicate
)
542 if (fromInclusive
> toExclusive
)
543 throw new ArgumentException(SR
.Argument_ToExclusiveLessThanFromExclusive
);
544 if (predicate
== null)
545 throw new ArgumentNullException(nameof(predicate
));
547 for (int i
= fromInclusive
; i
< toExclusive
; i
++)
548 if (!predicate(i
)) return false;
554 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
555 /// for all elements in the <paramref name="collection"/>.
557 /// <param name="collection">The collection from which elements will be drawn from to pass to <paramref name="predicate"/>.</param>
558 /// <param name="predicate">Function that is evaluated on elements from <paramref name="collection"/>.</param>
559 /// <returns><c>true</c> if and only if <paramref name="predicate"/> returns <c>true</c> for all elements in
560 /// <paramref name="collection"/>.</returns>
561 /// <seealso cref="System.Collections.Generic.List<T>.TrueForAll"/>
563 public static bool ForAll
<T
>(IEnumerable
<T
> collection
, Predicate
<T
> predicate
)
565 if (collection
== null)
566 throw new ArgumentNullException(nameof(collection
));
567 if (predicate
== null)
568 throw new ArgumentNullException(nameof(predicate
));
570 foreach (T t
in collection
)
571 if (!predicate(t
)) return false;
580 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
581 /// for any integer starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.
583 /// <param name="fromInclusive">First integer to pass to <paramref name="predicate"/>.</param>
584 /// <param name="toExclusive">One greater than the last integer to pass to <paramref name="predicate"/>.</param>
585 /// <param name="predicate">Function that is evaluated from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</param>
586 /// <returns><c>true</c> if <paramref name="predicate"/> returns <c>true</c> for any integer
587 /// starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</returns>
588 /// <seealso cref="System.Collections.Generic.List<T>.Exists"/>
590 public static bool Exists(int fromInclusive
, int toExclusive
, Predicate
<int> predicate
)
592 if (fromInclusive
> toExclusive
)
593 throw new ArgumentException(SR
.Argument_ToExclusiveLessThanFromExclusive
);
594 if (predicate
== null)
595 throw new ArgumentNullException(nameof(predicate
));
597 for (int i
= fromInclusive
; i
< toExclusive
; i
++)
598 if (predicate(i
)) return true;
603 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
604 /// for any element in the <paramref name="collection"/>.
606 /// <param name="collection">The collection from which elements will be drawn from to pass to <paramref name="predicate"/>.</param>
607 /// <param name="predicate">Function that is evaluated on elements from <paramref name="collection"/>.</param>
608 /// <returns><c>true</c> if and only if <paramref name="predicate"/> returns <c>true</c> for an element in
609 /// <paramref name="collection"/>.</returns>
610 /// <seealso cref="System.Collections.Generic.List<T>.Exists"/>
612 public static bool Exists
<T
>(IEnumerable
<T
> collection
, Predicate
<T
> predicate
)
614 if (collection
== null)
615 throw new ArgumentNullException(nameof(collection
));
616 if (predicate
== null)
617 throw new ArgumentNullException(nameof(predicate
));
619 foreach (T t
in collection
)
620 if (predicate(t
)) return true;
626 #endregion Quantifiers
634 /// Marker to indicate the end of the contract section of a method.
636 [Conditional("CONTRACTS_FULL")]
637 public static void EndContractBlock() { }
641 #endregion User Methods
643 #region Private Methods
646 /// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
647 /// It is NEVER used to indicate failure of actual contracts at runtime.
649 private static void AssertMustUseRewriter(ContractFailureKind kind
, string contractKind
)
651 // For better diagnostics, report which assembly is at fault. Walk up stack and
652 // find the first non-mscorlib assembly.
653 Assembly thisAssembly
= typeof(Contract
).Assembly
; // In case we refactor mscorlib, use Contract class instead of Object.
654 StackTrace stack
= new StackTrace();
655 Assembly
? probablyNotRewritten
= null;
656 for (int i
= 0; i
< stack
.FrameCount
; i
++)
658 Assembly
? caller
= stack
.GetFrame(i
)!.GetMethod()?.DeclaringType
!.Assembly
;
659 if (caller
!= null && caller
!= thisAssembly
)
661 probablyNotRewritten
= caller
;
666 if (probablyNotRewritten
== null)
667 probablyNotRewritten
= thisAssembly
;
668 string? simpleName
= probablyNotRewritten
.GetName().Name
;
669 System
.Runtime
.CompilerServices
.ContractHelper
.TriggerFailure(kind
, SR
.Format(SR
.MustUseCCRewrite
, contractKind
, simpleName
), null, null, null);
672 #endregion Private Methods
674 #region Failure Behavior
677 /// Without contract rewriting, failing Assert/Assumes end up calling this method.
678 /// Code going through the contract rewriter never calls this method. Instead, the rewriter produced failures call
679 /// System.Runtime.CompilerServices.ContractHelper.RaiseContractFailedEvent, followed by
680 /// System.Runtime.CompilerServices.ContractHelper.TriggerFailure.
682 [System
.Diagnostics
.DebuggerNonUserCode
]
683 private static void ReportFailure(ContractFailureKind failureKind
, string? userMessage
, string? conditionText
, Exception
? innerException
)
685 if (failureKind
< ContractFailureKind
.Precondition
|| failureKind
> ContractFailureKind
.Assume
)
686 throw new ArgumentException(SR
.Format(SR
.Arg_EnumIllegalVal
, failureKind
), nameof(failureKind
));
688 // displayMessage == null means: yes we handled it. Otherwise it is the localized failure message
689 var displayMessage
= System
.Runtime
.CompilerServices
.ContractHelper
.RaiseContractFailedEvent(failureKind
, userMessage
, conditionText
, innerException
);
691 if (displayMessage
== null)
694 System
.Runtime
.CompilerServices
.ContractHelper
.TriggerFailure(failureKind
, displayMessage
, userMessage
, conditionText
, innerException
);
698 /// Allows a managed application environment such as an interactive interpreter (IronPython)
699 /// to be notified of contract failures and
700 /// potentially "handle" them, either by throwing a particular exception type, etc. If any of the
701 /// event handlers sets the Cancel flag in the ContractFailedEventArgs, then the Contract class will
702 /// not pop up an assert dialog box or trigger escalation policy. Hooking this event requires
703 /// full trust, because it will inform you of bugs in the appdomain and because the event handler
704 /// could allow you to continue execution.
706 public static event EventHandler
<ContractFailedEventArgs
> ContractFailed
710 System
.Runtime
.CompilerServices
.ContractHelper
.InternalContractFailed
+= value;
714 System
.Runtime
.CompilerServices
.ContractHelper
.InternalContractFailed
-= value;
718 #endregion Failure Behavior
721 [System
.Runtime
.CompilerServices
.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
722 public enum ContractFailureKind
726 PostconditionOnException
,
731 } // namespace System.Runtime.CompilerServices