A C# Helper class to validate parameters.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#pragma warning disable SA1402 // FileMayOnlyContainASingleClass. This is a ported class from ObjectModel.
namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Resources;
/// <summary>
/// Helper to validate parameters.
/// </summary>
public static class ValidateArg
{
/// <summary>
/// Throws ArgumentNullException if the argument is null, otherwise passes it through.
/// </summary>
/// <typeparam name="T">
/// Type to validate.
/// </typeparam>
/// <param name="arg">
/// The argument to check.
/// </param>
/// <param name="parameterName">
/// The parameter name of the argument.
/// </param>
/// <returns>
/// Type of argument.
/// </returns>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static T NotNull<T>([ValidatedNotNull]T arg, string parameterName)
where T : class
{
if (arg == null)
{
throw new ArgumentNullException(parameterName);
}
return arg;
}
/// <summary>
/// Validate a string is not null or empty.
/// </summary>
/// <param name="arg">
/// Input string.
/// </param>
/// <param name="parameterName">
/// Name of the parameter to validate.
/// </param>
/// <returns>
/// Validated string.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown if the input string is null or empty.
/// </exception>
[DebuggerStepThrough]
public static string NotNullOrEmpty([ValidatedNotNull]string arg, string parameterName)
{
if (string.IsNullOrEmpty(arg))
{
throw new ArgumentNullException(parameterName);
}
return arg;
}
/// <summary>
/// Validate a string is not null, empty or consists only of white-space characters.
/// </summary>
/// <param name="arg">
/// Input string.
/// </param>
/// <param name="parameterName">
/// Name of the parameter to validate.
/// </param>
/// <returns>
/// Validated string.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown if the input string is null null, empty or consists only of white-space characters.
/// </exception>
[DebuggerStepThrough]
public static string NotNullOrWhiteSpace([ValidatedNotNull]string arg, string parameterName)
{
if (string.IsNullOrWhiteSpace(arg))
{
throw new ArgumentNullException(parameterName);
}
return arg;
}
/// <summary>
/// Throws ArgumentOutOfRangeException if the argument is less than zero.
/// </summary>
/// <param name="arg">The argument to check.</param>
/// <param name="parameterName">The parameter name of the argument.</param>
[DebuggerStepThrough]
public static void NotNegative(int arg, string parameterName)
{
if (arg < 0)
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentIsNegative);
throw new ArgumentOutOfRangeException(parameterName, arg, message);
}
}
/// <summary>
/// Throws ArgumentOutOfRangeException if the argument is less than zero.
/// </summary>
/// <param name="arg">The argument to check.</param>
/// <param name="parameterName">The parameter name of the argument.</param>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static void NotNegative(long arg, string parameterName)
{
if (arg < 0)
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentIsNegative);
throw new ArgumentOutOfRangeException(parameterName, arg, message);
}
}
/// <summary>
/// Throws ArgumentNullException if the string is null, ArgumentException if the string is empty.
/// </summary>
/// <typeparam name="T">Type of parameter to validate.</typeparam>
/// <param name="arg">The argument to check.</param>
/// <param name="parameterName">The parameter name of the argument.</param>
[DebuggerStepThrough]
public static void NotNullOrEmpty<T>([ValidatedNotNull]IEnumerable<T> arg, string parameterName)
{
NotNull(arg, parameterName);
if (!arg.Any())
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentIsEmpty);
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Throws ArgumentNullException if the argument is null, ArgumentException if the argument is not the correct type.
/// </summary>
/// <param name="arg">The argument to check.</param>
/// <param name="parameterName">The parameter name of the argument.</param>
/// <typeparam name="T">The type of the expected argument.</typeparam>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "This is shared source. This method may not be called in the current assembly.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static void TypeOf<T>([ValidatedNotNull]object arg, string parameterName)
where T : class
{
NotNull(arg, parameterName);
if (!(arg is T))
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentNotTypeOf, typeof(T).FullName);
throw new ArgumentException(message, parameterName);
}
}
}
/// <summary>
/// Helper to validate parameter properties.
/// </summary>
public static class ValidateArgProperty
{
/// <summary>
/// Throws ArgumentException if the argument is null.
/// </summary>
/// <param name="arg">The argument to check (e.g. <c>Param1.PropertyA</c>).</param>
/// <param name="parameterName">The parameter name of the argument.</param>
/// <param name="propertyName">The property name of the argument.</param>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static void NotNull([ValidatedNotNull]object arg, string parameterName, string propertyName)
{
if (arg == null)
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentPropertyIsNull, propertyName);
throw new ArgumentNullException(parameterName, message);
}
}
/// <summary>
/// Throws ArgumentException if the argument is less than zero.
/// </summary>
/// <param name="arg">The argument to check (e.g. <c>Param1.PropertyA</c>).</param>
/// <param name="parameterName">The parameter name of the argument.</param>
/// <param name="propertyName">The property name of the argument.</param>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static void NotNegative(int arg, string parameterName, string propertyName)
{
if (arg < 0)
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentPropertyIsNegative, propertyName);
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Throws ArgumentException if the argument string is null or empty.
/// </summary>
/// <param name="arg">The argument to check (e.g. <c>Param1.PropertyA</c>).</param>
/// <param name="parameterName">The parameter name of the argument.</param>
/// <param name="propertyName">The property name of the argument.</param>
[DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This is shared source. This method may not be called in the current assembly.")]
public static void NotNullOrEmpty([ValidatedNotNull]string arg, string parameterName, string propertyName)
{
NotNull(arg, parameterName, propertyName);
if (string.IsNullOrEmpty(arg))
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentPropertyIsEmpty, propertyName);
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Throws ArgumentException if the argument is null or is not the correct type.
/// </summary>
/// <param name="arg">The argument to check (e.g. <c>Param1.PropertyA</c>).</param>
/// <param name="parameterName">The parameter name of the argument.</param>
/// <param name="propertyName">The property name of the argument.</param>
/// <typeparam name="T">The type of the expected argument.</typeparam>
[DebuggerStepThrough]
public static void TypeOf<T>([ValidatedNotNull]object arg, string parameterName, string propertyName)
where T : class
{
NotNull(arg, parameterName, propertyName);
if (!(arg is T))
{
var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_ArgumentPropertyNotTypeOf, propertyName, typeof(T).FullName);
throw new ArgumentException(message, parameterName);
}
}
}
/// <summary>
/// Secret attribute that tells the CA1062 validate arguments rule that this method validates the argument is not null.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
internal sealed class ValidatedNotNullAttribute : Attribute
{
}
}