/************************************************************************************* Extended WPF Toolkit Copyright (C) 2007-2013 Xceed Software Inc. This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license For more features, controls, and fast professional support, pick up the Plus Edition at http://xceed.com/wpf_toolkit Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids ***********************************************************************************/ /**************************************************************************\ Copyright Microsoft Corporation. All Rights Reserved. \**************************************************************************/ // This file contains general utilities to aid in development. // Classes here generally shouldn't be exposed publicly since // they're not particular to any library functionality. // Because the classes here are internal, it's likely this file // might be included in multiple assemblies. namespace Standard { using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Threading; /// /// A static class for retail validated assertions. /// Instead of breaking into the debugger an exception is thrown. /// internal static class Verify { /// /// Ensure that the current thread's apartment state is what's expected. /// /// /// The required apartment state for the current thread. /// /// /// The message string for the exception to be thrown if the state is invalid. /// /// /// Thrown if the calling thread's apartment state is not the same as the requiredState. /// [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsApartmentState( ApartmentState requiredState, string message ) { if( Thread.CurrentThread.GetApartmentState() != requiredState ) { throw new InvalidOperationException( message ); } } /// /// Ensure that an argument is neither null nor empty. /// /// The string to validate. /// The name of the parameter that will be presented if an exception is thrown. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [SuppressMessage( "Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength" )] [DebuggerStepThrough] public static void IsNeitherNullNorEmpty( string value, string name ) { // catch caller errors, mixing up the parameters. Name should never be empty. Assert.IsNeitherNullNorEmpty( name ); // Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P const string errorMessage = "The parameter can not be either null or empty."; if( null == value ) { throw new ArgumentNullException( name, errorMessage ); } if( "" == value ) { throw new ArgumentException( errorMessage, name ); } } /// /// Ensure that an argument is neither null nor does it consist only of whitespace. /// /// The string to validate. /// The name of the parameter that will be presented if an exception is thrown. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [SuppressMessage( "Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength" )] [DebuggerStepThrough] public static void IsNeitherNullNorWhitespace( string value, string name ) { // catch caller errors, mixing up the parameters. Name should never be empty. Assert.IsNeitherNullNorEmpty( name ); // Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters."; if( null == value ) { throw new ArgumentNullException( name, errorMessage ); } if( "" == value.Trim() ) { throw new ArgumentException( errorMessage, name ); } } /// Verifies that an argument is not null. /// Type of the object to validate. Must be a class. /// The object to validate. /// The name of the parameter that will be presented if an exception is thrown. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsNotDefault( T obj, string name ) where T : struct { if( default( T ).Equals( obj ) ) { throw new ArgumentException( "The parameter must not be the default value.", name ); } } /// Verifies that an argument is not null. /// Type of the object to validate. Must be a class. /// The object to validate. /// The name of the parameter that will be presented if an exception is thrown. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsNotNull( T obj, string name ) where T : class { if( null == obj ) { throw new ArgumentNullException( name ); } } /// Verifies that an argument is null. /// Type of the object to validate. Must be a class. /// The object to validate. /// The name of the parameter that will be presented if an exception is thrown. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsNull( T obj, string name ) where T : class { if( null != obj ) { throw new ArgumentException( "The parameter must be null.", name ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void PropertyIsNotNull( T obj, string name ) where T : class { if( null == obj ) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, "The property {0} cannot be null at this time.", name ) ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void PropertyIsNull( T obj, string name ) where T : class { if( null != obj ) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, "The property {0} must be null at this time.", name ) ); } } /// /// Verifies the specified statement is true. Throws an ArgumentException if it's not. /// /// The statement to be verified as true. /// Name of the parameter to include in the ArgumentException. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsTrue( bool statement, string name ) { if( !statement ) { throw new ArgumentException( "", name ); } } /// /// Verifies the specified statement is true. Throws an ArgumentException if it's not. /// /// The statement to be verified as true. /// Name of the parameter to include in the ArgumentException. /// The message to include in the ArgumentException. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void IsTrue( bool statement, string name, string message ) { if( !statement ) { throw new ArgumentException( message, name ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void AreEqual( T expected, T actual, string parameterName, string message ) { if( null == expected ) { // Two nulls are considered equal, regardless of type semantics. if( null != actual && !actual.Equals( expected ) ) { throw new ArgumentException( message, parameterName ); } } else if( !expected.Equals( actual ) ) { throw new ArgumentException( message, parameterName ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void AreNotEqual( T notExpected, T actual, string parameterName, string message ) { if( null == notExpected ) { // Two nulls are considered equal, regardless of type semantics. if( null == actual || actual.Equals( notExpected ) ) { throw new ArgumentException( message, parameterName ); } } else if( notExpected.Equals( actual ) ) { throw new ArgumentException( message, parameterName ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void UriIsAbsolute( Uri uri, string parameterName ) { Verify.IsNotNull( uri, parameterName ); if( !uri.IsAbsoluteUri ) { throw new ArgumentException( "The URI must be absolute.", parameterName ); } } /// /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. /// /// The lower bound inclusive value. /// The value to verify. /// The upper bound exclusive value. [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void BoundedInteger( int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName ) { if( value < lowerBoundInclusive || value >= upperBoundExclusive ) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The integer value must be bounded with [{0}, {1})", lowerBoundInclusive, upperBoundExclusive ), parameterName ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void BoundedDoubleInc( double lowerBoundInclusive, double value, double upperBoundInclusive, string message, string parameter ) { if( value < lowerBoundInclusive || value > upperBoundInclusive ) { throw new ArgumentException( message, parameter ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void TypeSupportsInterface( Type type, Type interfaceType, string parameterName ) { Assert.IsNeitherNullNorEmpty( parameterName ); Verify.IsNotNull( type, "type" ); Verify.IsNotNull( interfaceType, "interfaceType" ); if( type.GetInterface( interfaceType.Name ) == null ) { throw new ArgumentException( "The type of this parameter does not support a required interface", parameterName ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] public static void FileExists( string filePath, string parameterName ) { Verify.IsNeitherNullNorEmpty( filePath, parameterName ); if( !File.Exists( filePath ) ) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "No file exists at \"{0}\"", filePath ), parameterName ); } } [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] [DebuggerStepThrough] internal static void ImplementsInterface( object parameter, Type interfaceType, string parameterName ) { Assert.IsNotNull( parameter ); Assert.IsNotNull( interfaceType ); Assert.IsTrue( interfaceType.IsInterface ); bool isImplemented = false; foreach( var ifaceType in parameter.GetType().GetInterfaces() ) { if( ifaceType == interfaceType ) { isImplemented = true; break; } } if( !isImplemented ) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString() ), parameterName ); } } } }