Skip to content

Instantly share code, notes, and snippets.

@j2jensen
Created April 28, 2014 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j2jensen/11377210 to your computer and use it in GitHub Desktop.
Save j2jensen/11377210 to your computer and use it in GitHub Desktop.
Truenorth.Utility.Contract.Require class, for Require.That() syntax
using System;
using JetBrains.Annotations;
namespace Truenorth.Utility.Contract
{
/// <summary>
/// Some utility methods to help us create assertions within our methods.
/// We would have liked to use Microsoft's CodeContracts, but they made them
/// too clunky.
/// </summary>
public static class Require
{
/// <summary>
/// Require that the given condition is true. If it is, do nothing.
/// If not, the RequirementFailed event is invoked and a
/// <see cref="RequirementFailedException"/> is thrown.
/// </summary>
/// <param name="requiredCondition">
/// The condition which must be true in order for execution to pass this point.
/// </param>
/// <param name="buildMessage">
/// The message (if any) to include with the RequirementFailedException.
/// </param>
/// <exception cref="RequirementFailedException">If the given condition is false.</exception>
[ContractAnnotation("requiredCondition:false => halt")]
public static void That(
bool requiredCondition,
[InstantHandle] Func<string> buildMessage = null)
{
That(requiredCondition, () => new RequirementFailedException(buildMessage == null ? null : buildMessage()));
}
/// <summary>
/// Require that the given condition is true. If it is, do nothing.
/// If not, the RequirementFailed event is invoked and an
/// <see cref="ArgumentException"/> is thrown.
/// </summary>
/// <param name="requiredCondition">
/// The condition which must be true in order for execution to pass this point.
/// </param>
/// <param name="buildMessage">
/// The message (if any) to include with the ArgumentException.
/// </param>
/// <exception cref="RequirementFailedException">If the given condition is false.</exception>
[ContractAnnotation("requiredCondition:false => halt")]
public static void ThatArgument(
bool requiredCondition,
[InstantHandle] Func<string> buildMessage = null)
{
That(requiredCondition, () => new ArgumentException(buildMessage == null ? null : buildMessage()));
}
/// <summary>
/// Require that the given condition is true. If it is, do nothing.
/// If not, the given delegate is used to create an exception, the RequirementFailed event is invoked,
/// and then the created exception is thrown.
/// </summary>
/// <typeparam name="TException">The type of exception to be thrown if the given condition is false.</typeparam>
/// <param name="requiredCondition">
/// The condition which must be true in order for execution to pass this point.
/// </param>
/// <param name="createException">
/// A delegate that will create the exception to be thrown if the given condition is false.
/// </param>
/// <exception cref="TException">If the given condition is false.</exception>
[ContractAnnotation("requiredCondition:false => halt")]
public static void That<TException>(
bool requiredCondition,
[InstantHandle] Func<TException> createException)
where TException : Exception
{
if (!requiredCondition)
{
throw createException();
}
}
}
}
@j2jensen
Copy link
Author

PS--The [ContractAnnotation] and [InstantHandle] attributes are hints to Resharper. If you don't use Resharper, you shouldn't need them.

@Rab815
Copy link

Rab815 commented Jul 8, 2014

Where is RequirementFailedException... this seems like a handy class to have but I can't find that type of Exception?

@j2jensen
Copy link
Author

    /// <summary>
    /// A general-case exception to indicate that a requirement failed.
    /// </summary>
    public class RequirementFailedException : Exception
    {
        public RequirementFailedException(string message) :
            base(message)
        {
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment