#if DISABLE_DBC || !DEBUG || PROFILE_SVELTO #define DISABLE_CHECKS using System.Diagnostics; #endif using System; namespace DBC.ECS { /// /// Design By Contract Checks. /// /// Each method generates an exception or /// a trace assertion statement if the contract is broken. /// /// /// This example shows how to call the Require method. /// Assume DBC_CHECK_PRECONDITION is defined. /// /// public void Test(int x) /// { /// try /// { /// Check.Require(x > 1, "x must be > 1"); /// } /// catch (System.Exception ex) /// { /// Console.WriteLine(ex.ToString()); /// } /// } /// /// If you wish to use trace assertion statements, intended for Debug scenarios, /// rather than exception handling then set /// /// Check.UseAssertions = true /// /// You can specify this in your application entry point and maybe make it /// dependent on conditional compilation flags or configuration file settings, e.g., /// /// #if DBC_USE_ASSERTIONS /// Check.UseAssertions = true; /// #endif /// /// You can direct output to a Trace listener. For example, you could insert /// /// Trace.Listeners.Clear(); /// Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); /// /// /// or direct output to a file or the Event Log. /// /// (Note: For ASP.NET clients use the Listeners collection /// of the Debug, not the Trace, object and, for a Release build, only exception-handling /// is possible.) /// /// static class Check { #region Interface /// /// Precondition check. /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Require(bool assertion, string message) { if (UseExceptions) { if (!assertion) throw new PreconditionException(message); } else { Trace.Assert(assertion, "Precondition: " + message); } } /// /// Precondition check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Require(bool assertion, string message, Exception inner) { if (UseExceptions) { if (!assertion) throw new PreconditionException(message, inner); } else { Trace.Assert(assertion, "Precondition: " + message); } } /// /// Precondition check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Require(bool assertion) { if (UseExceptions) { if (!assertion) throw new PreconditionException("Precondition failed."); } else { Trace.Assert(assertion, "Precondition failed."); } } /// /// Postcondition check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Ensure(bool assertion, string message) { if (UseExceptions) { if (!assertion) throw new PostconditionException(message); } else { Trace.Assert(assertion, "Postcondition: " + message); } } /// /// Postcondition check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Ensure(bool assertion, string message, Exception inner) { if (UseExceptions) { if (!assertion) throw new PostconditionException(message, inner); } else { Trace.Assert(assertion, "Postcondition: " + message); } } /// /// Postcondition check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Ensure(bool assertion) { if (UseExceptions) { if (!assertion) throw new PostconditionException("Postcondition failed."); } else { Trace.Assert(assertion, "Postcondition failed."); } } /// /// Invariant check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Invariant(bool assertion, string message) { if (UseExceptions) { if (!assertion) throw new InvariantException(message); } else { Trace.Assert(assertion, "Invariant: " + message); } } /// /// Invariant check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Invariant(bool assertion, string message, Exception inner) { if (UseExceptions) { if (!assertion) throw new InvariantException(message, inner); } else { Trace.Assert(assertion, "Invariant: " + message); } } /// /// Invariant check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Invariant(bool assertion) { if (UseExceptions) { if (!assertion) throw new InvariantException("Invariant failed."); } else { Trace.Assert(assertion, "Invariant failed."); } } /// /// Assertion check. /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Assert(bool assertion, string message) { if (UseExceptions) { if (!assertion) throw new AssertionException(message); } else { Trace.Assert(assertion, "Assertion: " + message); } } /// /// Assertion check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Assert(bool assertion, string message, Exception inner) { if (UseExceptions) { if (!assertion) throw new AssertionException(message, inner); } else { Trace.Assert(assertion, "Assertion: " + message); } } /// /// Assertion check. /// /// #if DISABLE_CHECKS [Conditional("__NEVER_DEFINED__")] #endif public static void Assert(bool assertion) { if (UseExceptions) { if (!assertion) throw new AssertionException("Assertion failed."); } else { Trace.Assert(assertion, "Assertion failed."); } } /// /// Set this if you wish to use Trace Assert statements /// instead of exception handling. /// (The Check class uses exception handling by default.) /// public static bool UseAssertions { get { return useAssertions; } set { useAssertions = value; } } #endregion // Interface #region Implementation // No creation /// /// Is exception handling being used? /// static bool UseExceptions { get { return !useAssertions; } } // Are trace assertion statements being used? // Default is to use exception handling. static bool useAssertions; #endregion // Implementation } // End Check internal class Trace { internal static void Assert(bool assertion, string v) { #if NETFX_CORE System.Diagnostics.Contracts.Contract.Assert(assertion, v); #else System.Diagnostics.Trace.Assert(assertion, v); #endif } } #region Exceptions /// /// Exception raised when a contract is broken. /// Catch this exception type if you wish to differentiate between /// any DesignByContract exception and other runtime exceptions. /// /// public class DesignByContractException : Exception { protected DesignByContractException() {} protected DesignByContractException(string message) : base(message) {} protected DesignByContractException(string message, Exception inner) : base(message, inner) {} } /// /// Exception raised when a precondition fails. /// public class PreconditionException : DesignByContractException { /// /// Precondition Exception. /// public PreconditionException() {} /// /// Precondition Exception. /// public PreconditionException(string message) : base(message) {} /// /// Precondition Exception. /// public PreconditionException(string message, Exception inner) : base(message, inner) {} } /// /// Exception raised when a postcondition fails. /// public class PostconditionException : DesignByContractException { /// /// Postcondition Exception. /// public PostconditionException() {} /// /// Postcondition Exception. /// public PostconditionException(string message) : base(message) {} /// /// Postcondition Exception. /// public PostconditionException(string message, Exception inner) : base(message, inner) {} } /// /// Exception raised when an invariant fails. /// public class InvariantException : DesignByContractException { /// /// Invariant Exception. /// public InvariantException() {} /// /// Invariant Exception. /// public InvariantException(string message) : base(message) {} /// /// Invariant Exception. /// public InvariantException(string message, Exception inner) : base(message, inner) {} } /// /// Exception raised when an assertion fails. /// public class AssertionException : DesignByContractException { /// /// Assertion Exception. /// public AssertionException() {} /// /// Assertion Exception. /// public AssertionException(string message) : base(message) {} /// /// Assertion Exception. /// public AssertionException(string message, Exception inner) : base(message, inner) {} } #endregion // Exception classes } // End Design By Contract