3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>Microsoft,mbarnett</OWNER>
12 ** Purpose: The contract class allows for expressing preconditions,
13 ** postconditions, and object invariants about methods in source
14 ** code for runtime checking & static analysis.
16 ** Two classes (Contract and ContractHelper) are split into partial classes
17 ** in order to share the public front for multiple platforms (this file)
18 ** while providing separate implementation details for each platform.
20 ===========================================================*/
21 #define DEBUG // The behavior of this contract library should be consistent regardless of build type.
24 #define FEATURE_UNTRUSTED_CALLERS
31 #define FEATURE_UNTRUSTED_CALLERS
32 #define FEATURE_RELIABILITY_CONTRACTS
33 #define FEATURE_SERIALIZATION
37 using System
.Collections
.Generic
;
38 using System
.Diagnostics
.CodeAnalysis
;
39 using System
.Diagnostics
.Contracts
;
41 #if FEATURE_RELIABILITY_CONTRACTS
42 using System
.Runtime
.ConstrainedExecution
;
44 #if FEATURE_UNTRUSTED_CALLERS
45 using System
.Security
;
46 using System
.Security
.Permissions
;
49 namespace System
.Diagnostics
.Contracts
{
54 /// Methods and classes marked with this attribute can be used within calls to Contract methods. Such methods not make any visible state changes.
56 [Conditional("CONTRACTS_FULL")]
57 [AttributeUsage(AttributeTargets
.Constructor
| AttributeTargets
.Method
| AttributeTargets
.Property
| AttributeTargets
.Event
| AttributeTargets
.Delegate
| AttributeTargets
.Class
| AttributeTargets
.Parameter
, AllowMultiple
= false, Inherited
= true)]
58 public sealed class PureAttribute
: Attribute
63 /// Types marked with this attribute specify that a separate type contains the contracts for this type.
65 [Conditional("CONTRACTS_FULL")]
66 [Conditional("DEBUG")]
67 [AttributeUsage(AttributeTargets
.Class
| AttributeTargets
.Interface
| AttributeTargets
.Delegate
, AllowMultiple
= false, Inherited
= false)]
68 public sealed class ContractClassAttribute
: Attribute
70 private Type _typeWithContracts
;
72 public ContractClassAttribute(Type typeContainingContracts
)
74 _typeWithContracts
= typeContainingContracts
;
77 public Type TypeContainingContracts
{
78 get { return _typeWithContracts; }
83 /// Types marked with this attribute specify that they are a contract for the type that is the argument of the constructor.
85 [Conditional("CONTRACTS_FULL")]
86 [AttributeUsage(AttributeTargets
.Class
, AllowMultiple
= false, Inherited
= false)]
87 public sealed class ContractClassForAttribute
: Attribute
89 private Type _typeIAmAContractFor
;
91 public ContractClassForAttribute(Type typeContractsAreFor
)
93 _typeIAmAContractFor
= typeContractsAreFor
;
96 public Type TypeContractsAreFor
{
97 get { return _typeIAmAContractFor; }
102 /// This attribute is used to mark a method as being the invariant
103 /// method for a class. The method can have any name, but it must
104 /// return "void" and take no parameters. The body of the method
105 /// must consist solely of one or more calls to the method
106 /// Contract.Invariant. A suggested name for the method is
107 /// "ObjectInvariant".
109 [Conditional("CONTRACTS_FULL")]
110 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false, Inherited
= false)]
111 public sealed class ContractInvariantMethodAttribute
: Attribute
116 /// Attribute that specifies that an assembly is a reference assembly with contracts.
118 [AttributeUsage(AttributeTargets
.Assembly
)]
119 public sealed class ContractReferenceAssemblyAttribute
: Attribute
124 /// Methods (and properties) marked with this attribute can be used within calls to Contract methods, but have no runtime behavior associated with them.
126 [Conditional("CONTRACTS_FULL")]
127 [AttributeUsage(AttributeTargets
.Method
| AttributeTargets
.Property
, AllowMultiple
= false, Inherited
= true)]
128 public sealed class ContractRuntimeIgnoredAttribute
: Attribute
133 #if FEATURE_SERIALIZATION
136 internal enum Mutability
138 Immutable, // read-only after construction, except for lazy initialization & caches
139 // Do we need a "deeply immutable" value?
141 HasInitializationPhase, // read-only after some point.
142 // Do we need a value for mutable types with read-only wrapper subclasses?
145 // Note: This hasn't been thought through in any depth yet. Consider it experimental.
146 // We should replace this with Joe's concepts.
147 [Conditional("CONTRACTS_FULL")]
148 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
149 [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "Thank you very much, but we like the names we've defined for the accessors")]
150 internal sealed class MutabilityAttribute : Attribute
152 private Mutability _mutabilityMarker;
154 public MutabilityAttribute(Mutability mutabilityMarker)
156 _mutabilityMarker = mutabilityMarker;
159 public Mutability Mutability {
160 get { return _mutabilityMarker; }
166 /// Instructs downstream tools whether to assume the correctness of this assembly, type or member without performing any verification or not.
167 /// Can use [ContractVerification(false)] to explicitly mark assembly, type or member as one to *not* have verification performed on it.
168 /// Most specific element found (member, type, then assembly) takes precedence.
169 /// (That is useful if downstream tools allow a user to decide which polarity is the default, unmarked case.)
172 /// Apply this attribute to a type to apply to all members of the type, including nested types.
173 /// Apply this attribute to an assembly to apply to all types and members of the assembly.
174 /// Apply this attribute to a property to apply to both the getter and setter.
176 [Conditional("CONTRACTS_FULL")]
177 [AttributeUsage(AttributeTargets
.Assembly
| AttributeTargets
.Class
| AttributeTargets
.Struct
| AttributeTargets
.Method
| AttributeTargets
.Constructor
| AttributeTargets
.Property
)]
178 public sealed class ContractVerificationAttribute
: Attribute
182 public ContractVerificationAttribute(bool value) { _value = value; }
185 get { return _value; }
190 /// Allows a field f to be used in the method contracts for a method m when f has less visibility than m.
191 /// For instance, if the method is public, but the field is private.
193 [Conditional("CONTRACTS_FULL")]
194 [AttributeUsage(AttributeTargets
.Field
)]
195 [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification
= "Thank you very much, but we like the names we've defined for the accessors")]
196 public sealed class ContractPublicPropertyNameAttribute
: Attribute
198 private String _publicName
;
200 public ContractPublicPropertyNameAttribute(String name
)
206 get { return _publicName; }
211 /// Enables factoring legacy if-then-throw into separate methods for reuse and full control over
212 /// thrown exception and arguments
214 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false)]
215 [Conditional("CONTRACTS_FULL")]
216 public sealed class ContractArgumentValidatorAttribute
: Attribute
221 /// Enables writing abbreviations for contracts that get copied to other methods
223 [AttributeUsage(AttributeTargets
.Method
, AllowMultiple
= false)]
224 [Conditional("CONTRACTS_FULL")]
225 public sealed class ContractAbbreviatorAttribute
: Attribute
230 /// Allows setting contract and tool options at assembly, type, or method granularity.
232 [AttributeUsage(AttributeTargets
.All
, AllowMultiple
= true, Inherited
= false)]
233 [Conditional("CONTRACTS_FULL")]
234 public sealed class ContractOptionAttribute
: Attribute
236 private String _category
;
237 private String _setting
;
238 private bool _enabled
;
239 private String _value
;
241 public ContractOptionAttribute(String category
, String setting
, bool enabled
)
243 _category
= category
;
248 public ContractOptionAttribute(String category
, String setting
, String
value)
250 _category
= category
;
255 public String Category
{
256 get { return _category; }
259 public String Setting
{
260 get { return _setting; }
263 public bool Enabled
{
264 get { return _enabled; }
267 public String Value
{
268 get { return _value; }
272 #endregion Attributes
275 /// Contains static methods for representing program contracts such as preconditions, postconditions, and invariants.
278 /// WARNING: A binary rewriter must be used to insert runtime enforcement of these contracts.
279 /// Otherwise some contracts like Ensures can only be checked statically and will not throw exceptions during runtime when contracts are violated.
280 /// Please note this class uses conditional compilation to help avoid easy mistakes. Defining the preprocessor
281 /// symbol CONTRACTS_PRECONDITIONS will include all preconditions expressed using Contract.Requires in your
282 /// build. The symbol CONTRACTS_FULL will include postconditions and object invariants, and requires the binary rewriter.
284 public static partial class Contract
291 /// 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.
293 /// <param name="condition">Expression to assume will always be true.</param>
295 /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
298 [Conditional("DEBUG")]
299 [Conditional("CONTRACTS_FULL")]
300 #if FEATURE_RELIABILITY_CONTRACTS
301 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
303 public static void Assume(bool condition
)
306 ReportFailure(ContractFailureKind
.Assume
, null, null, null);
311 /// 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.
313 /// <param name="condition">Expression to assume will always be true.</param>
314 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
316 /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
319 [Conditional("DEBUG")]
320 [Conditional("CONTRACTS_FULL")]
321 #if FEATURE_RELIABILITY_CONTRACTS
322 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
324 public static void Assume(bool condition
, String userMessage
)
327 ReportFailure(ContractFailureKind
.Assume
, userMessage
, null, null);
336 /// In debug builds, perform a runtime check that <paramref name="condition"/> is true.
338 /// <param name="condition">Expression to check to always be true.</param>
340 [Conditional("DEBUG")]
341 [Conditional("CONTRACTS_FULL")]
342 #if FEATURE_RELIABILITY_CONTRACTS
343 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
345 public static void Assert(bool condition
)
348 ReportFailure(ContractFailureKind
.Assert
, null, null, null);
352 /// In debug builds, perform a runtime check that <paramref name="condition"/> is true.
354 /// <param name="condition">Expression to check to always be true.</param>
355 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
357 [Conditional("DEBUG")]
358 [Conditional("CONTRACTS_FULL")]
359 #if FEATURE_RELIABILITY_CONTRACTS
360 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
362 public static void Assert(bool condition
, String userMessage
)
365 ReportFailure(ContractFailureKind
.Assert
, userMessage
, null, null);
373 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
375 /// <param name="condition">Boolean expression representing the contract.</param>
377 /// This call must happen at the beginning of a method or property before any other code.
378 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
379 /// Use this form when backward compatibility does not force you to throw a particular exception.
382 [Conditional("CONTRACTS_FULL")]
383 #if FEATURE_RELIABILITY_CONTRACTS
384 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
386 public static void Requires(bool condition
)
388 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires");
392 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
394 /// <param name="condition">Boolean expression representing the contract.</param>
395 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
397 /// This call must happen at the beginning of a method or property before any other code.
398 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
399 /// Use this form when backward compatibility does not force you to throw a particular exception.
402 [Conditional("CONTRACTS_FULL")]
403 #if FEATURE_RELIABILITY_CONTRACTS
404 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
406 public static void Requires(bool condition
, String userMessage
)
408 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires");
412 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
414 /// <param name="condition">Boolean expression representing the contract.</param>
416 /// This call must happen at the beginning of a method or property before any other code.
417 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
418 /// Use this form when you want to throw a particular exception.
420 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId
= "condition")]
421 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
423 #if FEATURE_RELIABILITY_CONTRACTS
424 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
426 public static void Requires
<TException
>(bool condition
) where TException
: Exception
428 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires<TException>");
432 /// Specifies a contract such that the expression <paramref name="condition"/> must be true before the enclosing method or property is invoked.
434 /// <param name="condition">Boolean expression representing the contract.</param>
435 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
437 /// This call must happen at the beginning of a method or property before any other code.
438 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
439 /// Use this form when you want to throw a particular exception.
441 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId
= "userMessage")]
442 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId
= "condition")]
443 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
445 #if FEATURE_RELIABILITY_CONTRACTS
446 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
448 public static void Requires
<TException
>(bool condition
, String userMessage
) where TException
: Exception
450 AssertMustUseRewriter(ContractFailureKind
.Precondition
, "Requires<TException>");
458 /// Specifies a public contract such that the expression <paramref name="condition"/> will be true when the enclosing method or property returns normally.
460 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
462 /// This call must happen at the beginning of a method or property before any other code.
463 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
464 /// The contract rewriter must be used for runtime enforcement of this postcondition.
467 [Conditional("CONTRACTS_FULL")]
468 #if FEATURE_RELIABILITY_CONTRACTS
469 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
471 public static void Ensures(bool condition
)
473 AssertMustUseRewriter(ContractFailureKind
.Postcondition
, "Ensures");
477 /// Specifies a public contract such that the expression <paramref name="condition"/> will be true when the enclosing method or property returns normally.
479 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
480 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
482 /// This call must happen at the beginning of a method or property before any other code.
483 /// This contract is exposed to clients so must only reference members at least as visible as the enclosing method.
484 /// The contract rewriter must be used for runtime enforcement of this postcondition.
487 [Conditional("CONTRACTS_FULL")]
488 #if FEATURE_RELIABILITY_CONTRACTS
489 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
491 public static void Ensures(bool condition
, String userMessage
)
493 AssertMustUseRewriter(ContractFailureKind
.Postcondition
, "Ensures");
497 /// 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.
499 /// <typeparam name="TException">Type of exception related to this postcondition.</typeparam>
500 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
502 /// This call must happen at the beginning of a method or property before any other code.
503 /// This contract is exposed to clients so must only reference types and members at least as visible as the enclosing method.
504 /// The contract rewriter must be used for runtime enforcement of this postcondition.
507 [Conditional("CONTRACTS_FULL")]
508 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification
= "Exception type used in tools.")]
509 #if FEATURE_RELIABILITY_CONTRACTS
510 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
512 public static void EnsuresOnThrow
<TException
>(bool condition
) where TException
: Exception
514 AssertMustUseRewriter(ContractFailureKind
.PostconditionOnException
, "EnsuresOnThrow");
518 /// 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.
520 /// <typeparam name="TException">Type of exception related to this postcondition.</typeparam>
521 /// <param name="condition">Boolean expression representing the contract. May include <seealso cref="OldValue"/> and <seealso cref="Result"/>.</param>
522 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
524 /// This call must happen at the beginning of a method or property before any other code.
525 /// This contract is exposed to clients so must only reference types and members at least as visible as the enclosing method.
526 /// The contract rewriter must be used for runtime enforcement of this postcondition.
529 [Conditional("CONTRACTS_FULL")]
530 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification
= "Exception type used in tools.")]
531 #if FEATURE_RELIABILITY_CONTRACTS
532 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
534 public static void EnsuresOnThrow
<TException
>(bool condition
, String userMessage
) where TException
: Exception
536 AssertMustUseRewriter(ContractFailureKind
.PostconditionOnException
, "EnsuresOnThrow");
539 #region Old, Result, and Out Parameters
542 /// Represents the result (a.k.a. return value) of a method or property.
544 /// <typeparam name="T">Type of return value of the enclosing method or property.</typeparam>
545 /// <returns>Return value of the enclosing method or property.</returns>
547 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
549 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification
= "Not intended to be called at runtime.")]
551 #if FEATURE_RELIABILITY_CONTRACTS
552 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
554 public static T Result
<T
>() { return default(T); }
557 /// Represents the final (output) value of an out parameter when returning from a method.
559 /// <typeparam name="T">Type of the out parameter.</typeparam>
560 /// <param name="value">The out parameter.</param>
561 /// <returns>The output value of the out parameter.</returns>
563 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
565 [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId
= "0#", Justification
= "Not intended to be called at runtime.")]
567 #if FEATURE_RELIABILITY_CONTRACTS
568 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
570 public static T ValueAtReturn
<T
>(out T
value) { value = default(T); return value; }
573 /// Represents the value of <paramref name="value"/> as it was at the start of the method or property.
575 /// <typeparam name="T">Type of <paramref name="value"/>. This can be inferred.</typeparam>
576 /// <param name="value">Value to represent. This must be a field or parameter.</param>
577 /// <returns>Value of <paramref name="value"/> at the start of the method or property.</returns>
579 /// This method can only be used within the argument to the <seealso cref="Ensures(bool)"/> contract.
581 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId
= "value")]
583 #if FEATURE_RELIABILITY_CONTRACTS
584 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
586 public static T OldValue
<T
>(T
value) { return default(T); }
588 #endregion Old, Result, and Out Parameters
595 /// Specifies a contract such that the expression <paramref name="condition"/> will be true after every method or property on the enclosing class.
597 /// <param name="condition">Boolean expression representing the contract.</param>
599 /// This contact can only be specified in a dedicated invariant method declared on a class.
600 /// This contract is not exposed to clients so may reference members less visible as the enclosing method.
601 /// The contract rewriter must be used for runtime enforcement of this invariant.
604 [Conditional("CONTRACTS_FULL")]
605 #if FEATURE_RELIABILITY_CONTRACTS
606 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
608 public static void Invariant(bool condition
)
610 AssertMustUseRewriter(ContractFailureKind
.Invariant
, "Invariant");
614 /// Specifies a contract such that the expression <paramref name="condition"/> will be true after every method or property on the enclosing class.
616 /// <param name="condition">Boolean expression representing the contract.</param>
617 /// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
619 /// This contact can only be specified in a dedicated invariant method declared on a class.
620 /// This contract is not exposed to clients so may reference members less visible as the enclosing method.
621 /// The contract rewriter must be used for runtime enforcement of this invariant.
624 [Conditional("CONTRACTS_FULL")]
625 #if FEATURE_RELIABILITY_CONTRACTS
626 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
628 public static void Invariant(bool condition
, String userMessage
)
630 AssertMustUseRewriter(ContractFailureKind
.Invariant
, "Invariant");
640 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
641 /// for all integers starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.
643 /// <param name="fromInclusive">First integer to pass to <paramref name="predicate"/>.</param>
644 /// <param name="toExclusive">One greater than the last integer to pass to <paramref name="predicate"/>.</param>
645 /// <param name="predicate">Function that is evaluated from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</param>
646 /// <returns><c>true</c> if <paramref name="predicate"/> returns <c>true</c> for all integers
647 /// starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</returns>
648 /// <seealso cref="System.Collections.Generic.List<T>.TrueForAll"/>
650 #if FEATURE_RELIABILITY_CONTRACTS
651 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)] // Assumes predicate obeys CER rules.
653 public static bool ForAll(int fromInclusive
, int toExclusive
, Predicate
<int> predicate
)
655 if (fromInclusive
> toExclusive
)
657 throw new ArgumentException(Environment
.GetResourceString("Argument_ToExclusiveLessThanFromExclusive"));
659 throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
661 if (predicate
== null)
662 throw new ArgumentNullException("predicate");
663 Contract
.EndContractBlock();
665 for (int i
= fromInclusive
; i
< toExclusive
; i
++)
666 if (!predicate(i
)) return false;
672 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
673 /// for all elements in the <paramref name="collection"/>.
675 /// <param name="collection">The collection from which elements will be drawn from to pass to <paramref name="predicate"/>.</param>
676 /// <param name="predicate">Function that is evaluated on elements from <paramref name="collection"/>.</param>
677 /// <returns><c>true</c> if and only if <paramref name="predicate"/> returns <c>true</c> for all elements in
678 /// <paramref name="collection"/>.</returns>
679 /// <seealso cref="System.Collections.Generic.List<T>.TrueForAll"/>
681 #if FEATURE_RELIABILITY_CONTRACTS
682 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)] // Assumes predicate & collection enumerator obey CER rules.
684 public static bool ForAll
<T
>(IEnumerable
<T
> collection
, Predicate
<T
> predicate
)
686 if (collection
== null)
687 throw new ArgumentNullException("collection");
688 if (predicate
== null)
689 throw new ArgumentNullException("predicate");
690 Contract
.EndContractBlock();
692 foreach (T t
in collection
)
693 if (!predicate(t
)) return false;
702 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
703 /// for any integer starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.
705 /// <param name="fromInclusive">First integer to pass to <paramref name="predicate"/>.</param>
706 /// <param name="toExclusive">One greater than the last integer to pass to <paramref name="predicate"/>.</param>
707 /// <param name="predicate">Function that is evaluated from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</param>
708 /// <returns><c>true</c> if <paramref name="predicate"/> returns <c>true</c> for any integer
709 /// starting from <paramref name="fromInclusive"/> to <paramref name="toExclusive"/> - 1.</returns>
710 /// <seealso cref="System.Collections.Generic.List<T>.Exists"/>
712 #if FEATURE_RELIABILITY_CONTRACTS
713 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)] // Assumes predicate obeys CER rules.
715 public static bool Exists(int fromInclusive
, int toExclusive
, Predicate
<int> predicate
)
717 if (fromInclusive
> toExclusive
)
719 throw new ArgumentException(Environment
.GetResourceString("Argument_ToExclusiveLessThanFromExclusive"));
721 throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
723 if (predicate
== null)
724 throw new ArgumentNullException("predicate");
725 Contract
.EndContractBlock();
727 for (int i
= fromInclusive
; i
< toExclusive
; i
++)
728 if (predicate(i
)) return true;
733 /// Returns whether the <paramref name="predicate"/> returns <c>true</c>
734 /// for any element in the <paramref name="collection"/>.
736 /// <param name="collection">The collection from which elements will be drawn from to pass to <paramref name="predicate"/>.</param>
737 /// <param name="predicate">Function that is evaluated on elements from <paramref name="collection"/>.</param>
738 /// <returns><c>true</c> if and only if <paramref name="predicate"/> returns <c>true</c> for an element in
739 /// <paramref name="collection"/>.</returns>
740 /// <seealso cref="System.Collections.Generic.List<T>.Exists"/>
742 #if FEATURE_RELIABILITY_CONTRACTS
743 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)] // Assumes predicate & collection enumerator obey CER rules.
745 public static bool Exists
<T
>(IEnumerable
<T
> collection
, Predicate
<T
> predicate
)
747 if (collection
== null)
748 throw new ArgumentNullException("collection");
749 if (predicate
== null)
750 throw new ArgumentNullException("predicate");
751 Contract
.EndContractBlock();
753 foreach (T t
in collection
)
754 if (predicate(t
)) return true;
760 #endregion Quantifiers
764 #if FEATURE_UNSAFE_CONTRACTS
766 /// Runtime checking for pointer bounds is not currently feasible. Thus, at runtime, we just return
767 /// a very long extent for each pointer that is writable. As long as assertions are of the form
768 /// WritableBytes(ptr) >= ..., the runtime assertions will not fail.
769 /// The runtime value is 2^64 - 1 or 2^32 - 1.
771 [SuppressMessage("Microsoft.Performance", "CA1802", Justification
= "FxCop is confused")]
772 static readonly ulong MaxWritableExtent
= (UIntPtr
.Size
== 4) ? UInt32
.MaxValue
: UInt64
.MaxValue
;
775 /// Allows specifying a writable extent for a UIntPtr, similar to SAL's writable extent.
776 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
779 /// <param name="startAddress">Start of memory region</param>
780 /// <returns>The result is the number of bytes writable starting at <paramref name="startAddress"/></returns>
781 [CLSCompliant(false)]
783 [ContractRuntimeIgnored
]
784 #if FEATURE_RELIABILITY_CONTRACTS
785 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
787 public static ulong WritableBytes(UIntPtr startAddress
) { return MaxWritableExtent - startAddress.ToUInt64(); }
790 /// Allows specifying a writable extent for a UIntPtr, similar to SAL's writable extent.
791 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
794 /// <param name="startAddress">Start of memory region</param>
795 /// <returns>The result is the number of bytes writable starting at <paramref name="startAddress"/></returns>
796 [CLSCompliant(false)]
798 [ContractRuntimeIgnored
]
799 #if FEATURE_RELIABILITY_CONTRACTS
800 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
802 public static ulong WritableBytes(IntPtr startAddress
) { return MaxWritableExtent - (ulong)startAddress; }
805 /// Allows specifying a writable extent for a UIntPtr, similar to SAL's writable extent.
806 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
809 /// <param name="startAddress">Start of memory region</param>
810 /// <returns>The result is the number of bytes writable starting at <paramref name="startAddress"/></returns>
811 [CLSCompliant(false)]
813 [ContractRuntimeIgnored
]
815 #if FEATURE_RELIABILITY_CONTRACTS
816 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
820 unsafe public static ulong WritableBytes(void* startAddress
) { return MaxWritableExtent - (ulong)startAddress; }
823 /// Allows specifying a readable extent for a UIntPtr, similar to SAL's readable extent.
824 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
827 /// <param name="startAddress">Start of memory region</param>
828 /// <returns>The result is the number of bytes readable starting at <paramref name="startAddress"/></returns>
829 [CLSCompliant(false)]
831 [ContractRuntimeIgnored
]
832 #if FEATURE_RELIABILITY_CONTRACTS
833 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
835 public static ulong ReadableBytes(UIntPtr startAddress
) { return MaxWritableExtent - startAddress.ToUInt64(); }
838 /// Allows specifying a readable extent for a UIntPtr, similar to SAL's readable extent.
839 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
842 /// <param name="startAddress">Start of memory region</param>
843 /// <returns>The result is the number of bytes readable starting at <paramref name="startAddress"/></returns>
844 [CLSCompliant(false)]
846 [ContractRuntimeIgnored
]
847 #if FEATURE_RELIABILITY_CONTRACTS
848 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
850 public static ulong ReadableBytes(IntPtr startAddress
) { return MaxWritableExtent - (ulong)startAddress; }
853 /// Allows specifying a readable extent for a UIntPtr, similar to SAL's readable extent.
854 /// NOTE: this is for static checking only. No useful runtime code can be generated for this
857 /// <param name="startAddress">Start of memory region</param>
858 /// <returns>The result is the number of bytes readable starting at <paramref name="startAddress"/></returns>
859 [CLSCompliant(false)]
861 [ContractRuntimeIgnored
]
863 #if FEATURE_RELIABILITY_CONTRACTS
864 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
866 unsafe public static ulong ReadableBytes(void* startAddress
) { return MaxWritableExtent - (ulong)startAddress; }
867 #endif // FEATURE_UNSAFE_CONTRACTS
873 /// Marker to indicate the end of the contract section of a method.
875 [Conditional("CONTRACTS_FULL")]
876 #if FEATURE_RELIABILITY_CONTRACTS
877 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
879 public static void EndContractBlock() { }
883 #endregion User Methods
885 #region Failure Behavior
888 /// Without contract rewriting, failing Assert/Assumes end up calling this method.
889 /// Code going through the contract rewriter never calls this method. Instead, the rewriter produced failures call
890 /// System.Runtime.CompilerServices.ContractHelper.RaiseContractFailedEvent, followed by
891 /// System.Runtime.CompilerServices.ContractHelper.TriggerFailure.
893 static partial void ReportFailure(ContractFailureKind failureKind
, String userMessage
, String conditionText
, Exception innerException
);
896 /// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
897 /// It is NEVER used to indicate failure of actual contracts at runtime.
899 static partial void AssertMustUseRewriter(ContractFailureKind kind
, String contractKind
);
904 public enum ContractFailureKind
{
906 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId
= "Postcondition")]
908 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId
= "Postcondition")]
909 PostconditionOnException
,
918 // Note: In .NET FX 4.5, we duplicated the ContractHelper class in the System.Runtime.CompilerServices
919 // namespace to remove an ugly wart of a namespace from the Windows 8 profile. But we still need the
920 // old locations left around, so we can support rewritten .NET FX 4.0 libraries. Consider removing
921 // these from our reference assembly in a future version.
922 namespace System
.Diagnostics
.Contracts
.Internal
924 [Obsolete("Use the ContractHelper class in the System.Runtime.CompilerServices namespace instead.")]
925 public static class ContractHelper
927 #region Rewriter Failure Hooks
930 /// Rewriter will call this method on a contract failure to allow listeners to be notified.
931 /// The method should not perform any failure (assert/throw) itself.
933 /// <returns>null if the event was handled and should not trigger a failure.
934 /// Otherwise, returns the localized failure message</returns>
935 [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
936 [System
.Diagnostics
.DebuggerNonUserCode
]
937 #if FEATURE_RELIABILITY_CONTRACTS
938 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
940 public static string RaiseContractFailedEvent(ContractFailureKind failureKind
, String userMessage
, String conditionText
, Exception innerException
)
942 return System
.Runtime
.CompilerServices
.ContractHelper
.RaiseContractFailedEvent(failureKind
, userMessage
, conditionText
, innerException
);
946 /// Rewriter calls this method to get the default failure behavior.
948 [System
.Diagnostics
.DebuggerNonUserCode
]
949 #if FEATURE_RELIABILITY_CONTRACTS
950 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
952 public static void TriggerFailure(ContractFailureKind kind
, String displayMessage
, String userMessage
, String conditionText
, Exception innerException
)
954 System
.Runtime
.CompilerServices
.ContractHelper
.TriggerFailure(kind
, displayMessage
, userMessage
, conditionText
, innerException
);
957 #endregion Rewriter Failure Hooks
959 } // namespace System.Diagnostics.Contracts.Internal
962 namespace System
.Runtime
.CompilerServices
964 public static partial class ContractHelper
966 #region Rewriter Failure Hooks
969 /// Rewriter will call this method on a contract failure to allow listeners to be notified.
970 /// The method should not perform any failure (assert/throw) itself.
972 /// <returns>null if the event was handled and should not trigger a failure.
973 /// Otherwise, returns the localized failure message</returns>
974 [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
975 [System
.Diagnostics
.DebuggerNonUserCode
]
976 #if FEATURE_RELIABILITY_CONTRACTS
977 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
979 public static string RaiseContractFailedEvent(ContractFailureKind failureKind
, String userMessage
, String conditionText
, Exception innerException
)
981 var resultFailureMessage
= "Contract failed"; // default in case implementation does not assign anything.
982 RaiseContractFailedEventImplementation(failureKind
, userMessage
, conditionText
, innerException
, ref resultFailureMessage
);
983 return resultFailureMessage
;
988 /// Rewriter calls this method to get the default failure behavior.
990 [System
.Diagnostics
.DebuggerNonUserCode
]
991 #if FEATURE_RELIABILITY_CONTRACTS
992 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
994 public static void TriggerFailure(ContractFailureKind kind
, String displayMessage
, String userMessage
, String conditionText
, Exception innerException
)
996 TriggerFailureImplementation(kind
, displayMessage
, userMessage
, conditionText
, innerException
);
999 #endregion Rewriter Failure Hooks
1001 #region Implementation Stubs
1004 /// Rewriter will call this method on a contract failure to allow listeners to be notified.
1005 /// The method should not perform any failure (assert/throw) itself.
1006 /// This method has 3 functions:
1007 /// 1. Call any contract hooks (such as listeners to Contract failed events)
1008 /// 2. Determine if the listeneres deem the failure as handled (then resultFailureMessage should be set to null)
1009 /// 3. Produce a localized resultFailureMessage used in advertising the failure subsequently.
1011 /// <param name="resultFailureMessage">Should really be out (or the return value), but partial methods are not flexible enough.
1012 /// On exit: null if the event was handled and should not trigger a failure.
1013 /// Otherwise, returns the localized failure message</param>
1014 static partial void RaiseContractFailedEventImplementation(ContractFailureKind failureKind
, String userMessage
, String conditionText
, Exception innerException
, ref string resultFailureMessage
);
1017 /// Implements the default failure behavior of the platform. Under the BCL, it triggers an Assert box.
1019 static partial void TriggerFailureImplementation(ContractFailureKind kind
, String displayMessage
, String userMessage
, String conditionText
, Exception innerException
);
1021 #endregion Implementation Stubs
1023 } // namespace System.Runtime.CompilerServices