Files
Shrlalgo.RvKits/AntdWpf/Microsoft.Windows.Shell/Standard/Verify.cs

328 lines
14 KiB
C#
Raw Normal View History

2025-07-11 09:20:23 +08:00
using Standard;
2025-07-12 23:31:32 +08:00
// 该文件包含一般实用程序,用于帮助开发。
// 这里的类一般不应公开暴露,因为
// 它们与任何库函数无关。
// 因为这里的类是内部类,所以这个文件
// 可能包含在多个程序集中。
2025-07-11 09:20:23 +08:00
namespace AntdWpf.Microsoft.Windows.Shell.Standard
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Threading;
/// <summary>
2025-07-12 23:31:32 +08:00
/// 用于验证断言的静态类。
/// 不会进入调试器,而是抛出一个异常。
2025-07-11 09:20:23 +08:00
/// </summary>
internal static class Verify
{
/// <summary>
/// Ensure that the current thread's apartment state is what's expected.
/// </summary>
/// <param name="requiredState">
/// The required apartment state for the current thread.
/// </param>
/// <param name="message">
/// The message string for the exception to be thrown if the state is invalid.
/// </param>
/// <exception cref="InvalidOperationException">
/// Thrown if the calling thread's apartment state is not the same as the requiredState.
/// </exception>
[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);
}
}
/// <summary>
/// Ensure that an argument is neither null nor empty.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[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);
}
}
/// <summary>
/// Ensure that an argument is neither null nor does it consist only of whitespace.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[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);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotDefault<T>(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);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotNull<T>(T obj, string name) where T : class
{
if (null == obj)
{
Assert.Fail();
throw new ArgumentNullException(name);
}
}
/// <summary>Verifies that an argument is null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNull<T>(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>(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>(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));
}
}
/// <summary>
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
/// </summary>
/// <param name="statement">The statement to be verified as true.</param>
/// <param name="name">Name of the parameter to include in the ArgumentException.</param>
/// <param name="message">The message to include in the ArgumentException.</param>
[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>(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>(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);
}
}
/// <summary>
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
/// </summary>
/// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
/// <param name="value">The value to verify.</param>
/// <param name="upperBoundExclusive">The upper bound exclusive value.</param>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
[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);
}
}
}
}