// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace CommunityToolkit.Diagnostics; /// /// Helper methods to verify conditions when running code. /// [DebuggerStepThrough] public static partial class Guard { /// /// Asserts that the input value is . /// /// The type of reference value type being tested. /// The input value to test. /// The name of the input parameter being tested. /// Thrown if is not . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNull(T? value, [CallerArgumentExpression("value")] string name = "") { if (value is null) { return; } ThrowHelper.ThrowArgumentExceptionForIsNull(value, name); } /// /// Asserts that the input value is . /// /// The type of nullable value type being tested. /// The input value to test. /// The name of the input parameter being tested. /// Thrown if is not . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNull(T? value, [CallerArgumentExpression("value")] string name = "") where T : struct { if (value is null) { return; } ThrowHelper.ThrowArgumentExceptionForIsNull(value, name); } /// /// Asserts that the input value is not . /// /// The type of reference value type being tested. /// The input value to test. /// The name of the input parameter being tested. /// Thrown if is . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotNull([NotNull] T? value, [CallerArgumentExpression("value")] string name = "") { if (value is not null) { return; } ThrowHelper.ThrowArgumentNullExceptionForIsNotNull(name); } /// /// Asserts that the input value is not . /// /// The type of nullable value type being tested. /// The input value to test. /// The name of the input parameter being tested. /// Thrown if is . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotNull([NotNull] T? value, [CallerArgumentExpression("value")] string name = "") where T : struct { if (value is not null) { return; } ThrowHelper.ThrowArgumentNullExceptionForIsNotNull(name); } /// /// Asserts that the input value is of a specific type. /// /// The type of the input value. /// The input to test. /// The name of the input parameter being tested. /// Thrown if is not of type . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsOfType(object value, [CallerArgumentExpression("value")] string name = "") { if (value.GetType() == typeof(T)) { return; } ThrowHelper.ThrowArgumentExceptionForIsOfType(value, name); } /// /// Asserts that the input value is not of a specific type. /// /// The type of the input value. /// The input to test. /// The name of the input parameter being tested. /// Thrown if is of type . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotOfType(object value, [CallerArgumentExpression("value")] string name = "") { if (value.GetType() != typeof(T)) { return; } ThrowHelper.ThrowArgumentExceptionForIsNotOfType(value, name); } /// /// Asserts that the input value is of a specific type. /// /// The input to test. /// The type to look for. /// The name of the input parameter being tested. /// Thrown if the type of is not the same as . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsOfType(object value, Type type, [CallerArgumentExpression("value")] string name = "") { if (value.GetType() == type) { return; } ThrowHelper.ThrowArgumentExceptionForIsOfType(value, type, name); } /// /// Asserts that the input value is not of a specific type. /// /// The input to test. /// The type to look for. /// The name of the input parameter being tested. /// Thrown if the type of is the same as . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotOfType(object value, Type type, [CallerArgumentExpression("value")] string name = "") { if (value.GetType() != type) { return; } ThrowHelper.ThrowArgumentExceptionForIsNotOfType(value, type, name); } /// /// Asserts that the input value can be assigned to a specified type. /// /// The type to check the input value against. /// The input to test. /// The name of the input parameter being tested. /// Thrown if can't be assigned to type . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsAssignableToType(object value, [CallerArgumentExpression("value")] string name = "") { if (value is T) { return; } ThrowHelper.ThrowArgumentExceptionForIsAssignableToType(value, name); } /// /// Asserts that the input value can't be assigned to a specified type. /// /// The type to check the input value against. /// The input to test. /// The name of the input parameter being tested. /// Thrown if can be assigned to type . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotAssignableToType(object value, [CallerArgumentExpression("value")] string name = "") { if (value is not T) { return; } ThrowHelper.ThrowArgumentExceptionForIsNotAssignableToType(value, name); } /// /// Asserts that the input value can be assigned to a specified type. /// /// The input to test. /// The type to look for. /// The name of the input parameter being tested. /// Thrown if can't be assigned to . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsAssignableToType(object value, Type type, [CallerArgumentExpression("value")] string name = "") { if (type.IsInstanceOfType(value)) { return; } ThrowHelper.ThrowArgumentExceptionForIsAssignableToType(value, type, name); } /// /// Asserts that the input value can't be assigned to a specified type. /// /// The input to test. /// The type to look for. /// The name of the input parameter being tested. /// Thrown if can be assigned to . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsNotAssignableToType(object value, Type type, [CallerArgumentExpression("value")] string name = "") { if (!type.IsInstanceOfType(value)) { return; } ThrowHelper.ThrowArgumentExceptionForIsNotAssignableToType(value, type, name); } /// /// Asserts that the input value must be the same instance as the target value. /// /// The type of input values to compare. /// The input value to test. /// The target value to test for. /// The name of the input parameter being tested. /// Thrown if is not the same instance as . /// The method is generic to prevent using it with value types. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsReferenceEqualTo(T value, T target, [CallerArgumentExpression("value")] string name = "") where T : class { if (ReferenceEquals(value, target)) { return; } ThrowHelper.ThrowArgumentExceptionForIsReferenceEqualTo(name); } /// /// Asserts that the input value must not be the same instance as the target value. /// /// The type of input values to compare. /// The input value to test. /// The target value to test for. /// The name of the input parameter being tested. /// Thrown if is the same instance as . /// The method is generic to prevent using it with value types. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsReferenceNotEqualTo(T value, T target, [CallerArgumentExpression("value")] string name = "") where T : class { if (!ReferenceEquals(value, target)) { return; } ThrowHelper.ThrowArgumentExceptionForIsReferenceNotEqualTo(name); } }