using Standard; // 该文件包含一般实用程序,用于帮助开发。 // 这里的类一般不应公开暴露,因为 // 它们与任何库函数无关。 // 因为这里的类是内部类,所以这个文件 // 可能包含在多个程序集中。 namespace AntDesign.WPF.Microsoft.Windows.Shell.Standard { using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Threading; /// /// 用于验证断言的静态类。 /// 不会进入调试器,而是抛出一个异常。 /// 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) { Assert.Fail(); 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) { Assert.Fail(); throw new ArgumentNullException(name, errorMessage); } if ("" == value) { Assert.Fail(); 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) { Assert.Fail(); throw new ArgumentNullException(name, errorMessage); } if ("" == value.Trim()) { Assert.Fail(); 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)) { Assert.Fail(); 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) { Assert.Fail(); 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) { Assert.Fail(); 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) { Assert.Fail(); 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) { Assert.Fail(); 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. /// The message to include in the ArgumentException. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [DebuggerStepThrough] public static void IsTrue(bool statement, string name, string message = null) { if (!statement) { Assert.Fail(); throw new ArgumentException(message ?? "", name); } } [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [DebuggerStepThrough] public static void IsFalse(bool statement, string name, string message = null) { if (statement) { Assert.Fail(); 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)) { Assert.Fail(); throw new ArgumentException(message, parameterName); } } else if (!expected.Equals(actual)) { Assert.Fail(); 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)) { Assert.Fail(); throw new ArgumentException(message, parameterName); } } else if (notExpected.Equals(actual)) { Assert.Fail(); 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) { Assert.Fail(); 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. /// The name of the parameter that caused the current exception. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [DebuggerStepThrough] public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName) { if (value < lowerBoundInclusive || value >= upperBoundExclusive) { Assert.Fail(); 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) { Assert.Fail(); 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) { Assert.Fail(); 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)) { Assert.Fail(); 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) { Assert.Fail(); throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString()), parameterName); } } } }