Merge remote-tracking branch 'origin/master' into dev/split-controls

This commit is contained in:
michael-hawker 2021-01-28 15:51:03 -08:00
Родитель d09c667a0b 025a0ae074
Коммит 50c7c6bfe1
38 изменённых файлов: 2778 добавлений и 2167 удалений

Просмотреть файл

@ -12,7 +12,7 @@
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Просмотреть файл

@ -416,7 +416,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Controls
/// <summary>
/// The Local Storage Helper.
/// </summary>
private LocalObjectStorageHelper storage = new LocalObjectStorageHelper();
private LocalObjectStorageHelper storage = new LocalObjectStorageHelper(new SystemSerializer());
/// <summary>
/// DocFX note types and styling info, keyed by identifier.

Просмотреть файл

@ -42,7 +42,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
public static async void EnsureCacheLatest()
{
var settingsStorage = new LocalObjectStorageHelper();
var settingsStorage = new LocalObjectStorageHelper(new SystemSerializer());
var onlineDocsSHA = await GetDocsSHA();
var cacheSHA = settingsStorage.Read<string>(_cacheSHAKey);

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);
private static LinkedList<Sample> _recentSamples;
private static RoamingObjectStorageHelper _roamingObjectStorageHelper = new RoamingObjectStorageHelper();
private static LocalObjectStorageHelper _localObjectStorageHelper = new LocalObjectStorageHelper(new SystemSerializer());
public static async Task<SampleCategory> GetCategoryBySample(Sample sample)
{
@ -98,7 +98,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
if (_recentSamples == null)
{
_recentSamples = new LinkedList<Sample>();
var savedSamples = _roamingObjectStorageHelper.Read<string>(_recentSamplesStorageKey);
var savedSamples = _localObjectStorageHelper.Read<string>(_recentSamplesStorageKey);
if (savedSamples != null)
{
@ -144,7 +144,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
}
var str = string.Join(";", _recentSamples.Take(10).Select(s => s.Name).ToArray());
_roamingObjectStorageHelper.Save<string>(_recentSamplesStorageKey, str);
_localObjectStorageHelper.Save<string>(_recentSamplesStorageKey, str);
}
}
}

Просмотреть файл

@ -1,26 +1,33 @@
<Page
x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.ObjectStoragePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.ObjectStoragePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel Margin="20">
<ToggleSwitch x:Name="StorageModeToggle" HorizontalAlignment="Center"
OnContent="Roaming storage (save across all your devices)"
OffContent="Local storage (save on this device only)" />
<TextBox x:Name="KeyTextBox"
Margin="0,10,0,0"
PlaceholderText="Key" />
<TextBox x:Name="KeyTextBox" PlaceholderText="Key" Margin="0 10 0 0" />
<TextBox x:Name="ContentTextBox"
Margin="0,10,0,0"
PlaceholderText="Content to save" />
<TextBox x:Name="ContentTextBox" PlaceholderText="Content to save" Margin="0 10 0 0" />
<StackPanel Margin="0 10 0 0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="ReadButton" Content="Read from key" HorizontalAlignment="Center" Margin="5 0"
Click="ReadButton_Click" />
<Button x:Name="SaveButton" Content="Save" HorizontalAlignment="Center" Margin="5 0"
Click="SaveButton_Click" />
<StackPanel Margin="0,10,0,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button x:Name="ReadButton"
Margin="5,0"
HorizontalAlignment="Center"
Click="ReadButton_Click"
Content="Read from key" />
<Button x:Name="SaveButton"
Margin="5,0"
HorizontalAlignment="Center"
Click="SaveButton_Click"
Content="Save" />
</StackPanel>
</StackPanel>
</ScrollViewer>

Просмотреть файл

@ -9,8 +9,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
{
public sealed partial class ObjectStoragePage
{
private readonly IObjectStorageHelper localStorageHelper = new LocalObjectStorageHelper();
private readonly IObjectStorageHelper roamingStorageHelper = new RoamingObjectStorageHelper();
private readonly IObjectStorageHelper localStorageHelper = new LocalObjectStorageHelper(new SystemSerializer());
public ObjectStoragePage()
{
@ -24,21 +23,10 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
return;
}
if (StorageModeToggle.IsOn)
// Read from local storage
if (localStorageHelper.KeyExists(KeyTextBox.Text))
{
// Read from roaming storage
if (roamingStorageHelper.KeyExists(KeyTextBox.Text))
{
ContentTextBox.Text = roamingStorageHelper.Read<string>(KeyTextBox.Text);
}
}
else
{
// Read from local storage
if (localStorageHelper.KeyExists(KeyTextBox.Text))
{
ContentTextBox.Text = localStorageHelper.Read<string>(KeyTextBox.Text);
}
ContentTextBox.Text = localStorageHelper.Read<string>(KeyTextBox.Text);
}
}
@ -54,16 +42,8 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
return;
}
if (StorageModeToggle.IsOn)
{
// Save into roaming storage
roamingStorageHelper.Save(KeyTextBox.Text, ContentTextBox.Text);
}
else
{
// Save into local storage
localStorageHelper.Save(KeyTextBox.Text, ContentTextBox.Text);
}
// Save into local storage
localStorageHelper.Save(KeyTextBox.Text, ContentTextBox.Text);
}
}
}

Просмотреть файл

@ -21,14 +21,13 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <summary>
/// Initializes a new instance of the <see cref="BaseObjectStorageHelper"/> class,
/// which can read and write data using the provided <see cref="IObjectSerializer"/>;
/// if none is provided, a default Json serializer will be used (based on <see cref="DataContractSerializer"/>).
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json and the new default Serializer may behave differently.
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json.
/// To implement a <see cref="IObjectSerializer"/> based on Newtonsoft.Json or System.Text.Json see https://aka.ms/wct/storagehelper-migration
/// </summary>
/// <param name="objectSerializer">The serializer to use.</param>
public BaseObjectStorageHelper(IObjectSerializer objectSerializer = null)
public BaseObjectStorageHelper(IObjectSerializer objectSerializer)
{
serializer = objectSerializer ?? new JsonObjectSerializer();
serializer = objectSerializer ?? throw new ArgumentNullException(nameof(objectSerializer));
}
/// <summary>
@ -85,15 +84,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
return @default;
}
var type = typeof(T);
var typeInfo = type.GetTypeInfo();
if (typeInfo.IsPrimitive || type == typeof(string))
{
return (T)Convert.ChangeType(value, type);
}
return serializer.Deserialize<T>((string)value);
return serializer.Deserialize<T>(value);
}
/// <summary>
@ -132,14 +123,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
var type = typeof(T);
var typeInfo = type.GetTypeInfo();
if (typeInfo.IsPrimitive || type == typeof(string))
{
Settings.Values[key] = value;
}
else
{
Settings.Values[key] = serializer.Serialize(value);
}
Settings.Values[key] = serializer.Serialize(value);
}
/// <summary>
@ -214,7 +198,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <returns>The <see cref="StorageFile"/> where the object was saved</returns>
public Task<StorageFile> SaveFileAsync<T>(string filePath, T value)
{
return StorageFileHelper.WriteTextToFileAsync(Folder, serializer.Serialize(value), filePath, CreationCollisionOption.ReplaceExisting);
return StorageFileHelper.WriteTextToFileAsync(Folder, serializer.Serialize(value)?.ToString(), filePath, CreationCollisionOption.ReplaceExisting);
}
}
}

Просмотреть файл

@ -10,19 +10,19 @@ namespace Microsoft.Toolkit.Uwp.Helpers
public interface IObjectSerializer
{
/// <summary>
/// Serialize an object into a string.
/// Serialize an object into a string. It is recommended to use strings as the final format for objects if you plan to use the <see cref="BaseObjectStorageHelper.SaveFileAsync{T}(string, T)"/> method.
/// </summary>
/// <typeparam name="T">The type of the object to serialize.</typeparam>
/// <param name="value">The object to serialize.</param>
/// <returns>The serialized object.</returns>
string Serialize<T>(T value);
object Serialize<T>(T value);
/// <summary>
/// Deserialize a string into an object.
/// Deserialize a primitive or string into an object of the given type.
/// </summary>
/// <typeparam name="T">The type of the deserialized object.</typeparam>
/// <param name="value">The string to deserialize.</param>
/// <returns>The deserialized object.</returns>
T Deserialize<T>(string value);
T Deserialize<T>(object value);
}
}

Просмотреть файл

@ -1,29 +0,0 @@
// 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.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace Microsoft.Toolkit.Uwp.Helpers
{
internal class JsonObjectSerializer : IObjectSerializer
{
public string Serialize<T>(T value)
{
using var sr = new MemoryStream();
new DataContractJsonSerializer(typeof(T)).WriteObject(sr, value);
var json = sr.ToArray();
return Encoding.UTF8.GetString(json, 0, json.Length);
}
public T Deserialize<T>(string value)
{
using var ms = new MemoryStream(Encoding.UTF8.GetBytes(value));
return (T)new DataContractJsonSerializer(typeof(T)).ReadObject(ms);
}
}
}

Просмотреть файл

@ -15,12 +15,11 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <summary>
/// Initializes a new instance of the <see cref="LocalObjectStorageHelper"/> class,
/// which can read and write data using the provided <see cref="IObjectSerializer"/>;
/// if none is provided, a default Json serializer will be used (based on <see cref="DataContractSerializer"/>).
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json and the new default Serializer may behave differently.
/// To implement a <see cref="IObjectSerializer"/> based on Newtonsoft.Json or System.Text.Json see https://aka.ms/wct/storagehelper-migration
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json.
/// To implement an <see cref="IObjectSerializer"/> based on System.Text.Json, Newtonsoft.Json, or DataContractJsonSerializer see https://aka.ms/wct/storagehelper-migration
/// </summary>
/// <param name="objectSerializer">The serializer to use.</param>
public LocalObjectStorageHelper(IObjectSerializer objectSerializer = null)
public LocalObjectStorageHelper(IObjectSerializer objectSerializer)
: base(objectSerializer)
{
Settings = ApplicationData.Current.LocalSettings;

Просмотреть файл

@ -2,6 +2,7 @@
// 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.Runtime.Serialization;
using Windows.Storage;
@ -10,17 +11,17 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <summary>
/// Store data in the Roaming environment (shared across all user devices).
/// </summary>
[Obsolete("Package State Roaming will be removed in a futures Windows Update, see https://docs.microsoft.com/windows/deployment/planning/windows-10-deprecated-features for more information.")]
public class RoamingObjectStorageHelper : BaseObjectStorageHelper
{
/// <summary>
/// Initializes a new instance of the <see cref="RoamingObjectStorageHelper"/> class,
/// which can read and write data using the provided <see cref="IObjectSerializer"/>;
/// if none is provided, a default Json serializer will be used (based on <see cref="DataContractSerializer"/>).
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json and the new default Serializer may behave differently.
/// To implement a <see cref="IObjectSerializer"/> based on Newtonsoft.Json or System.Text.Json see https://aka.ms/wct/storagehelper-migration
/// In 6.1 and older the default Serializer was based on Newtonsoft.Json.
/// To implement an <see cref="IObjectSerializer"/> based on System.Text.Json, Newtonsoft.Json, or DataContractJsonSerializer see https://aka.ms/wct/storagehelper-migration
/// </summary>
/// <param name="objectSerializer">The serializer to use.</param>
public RoamingObjectStorageHelper(IObjectSerializer objectSerializer = null)
public RoamingObjectStorageHelper(IObjectSerializer objectSerializer)
: base(objectSerializer)
{
Settings = ApplicationData.Current.RoamingSettings;

Просмотреть файл

@ -0,0 +1,48 @@
// 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.Reflection;
using Microsoft.Toolkit.Diagnostics;
using Windows.Storage;
namespace Microsoft.Toolkit.Uwp.Helpers
{
/// <summary>
/// A bare-bones serializer which knows how to deal with primitive types and strings only. It will store them directly based on the <see cref="ApplicationDataContainer"/> API.
/// It is recommended for more complex scenarios to implement your own <see cref="IObjectSerializer"/> based on System.Text.Json, Newtonsoft.Json, or DataContractJsonSerializer see https://aka.ms/wct/storagehelper-migration
/// </summary>
public class SystemSerializer : IObjectSerializer
{
/// <summary>
/// Take a primitive value from storage and return it as the requested type using the <see cref="Convert.ChangeType(object, Type)"/> API.
/// </summary>
/// <typeparam name="T">Type to convert value to.</typeparam>
/// <param name="value">Value from storage to convert.</param>
/// <returns>Deserialized value or default value.</returns>
public T Deserialize<T>(object value)
{
var type = typeof(T);
var typeInfo = type.GetTypeInfo();
if (typeInfo.IsPrimitive || type == typeof(string))
{
return (T)Convert.ChangeType(value, type);
}
return ThrowHelper.ThrowNotSupportedException<T>("This serializer can only handle primitive types and strings. Please implement your own IObjectSerializer for more complex scenarios.");
}
/// <summary>
/// Returns the value so that it can be serialized by the <see cref="ApplicationDataContainer"/> API directly.
/// </summary>
/// <typeparam name="T">Type to serialize from.</typeparam>
/// <param name="value">Value to serialize.</param>
/// <returns>String representation of value.</returns>
public object Serialize<T>(T value)
{
return value;
}
}
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// </summary>
public sealed class SystemInformation
{
private readonly LocalObjectStorageHelper _localObjectStorageHelper = new LocalObjectStorageHelper();
private readonly LocalObjectStorageHelper _localObjectStorageHelper = new LocalObjectStorageHelper(new SystemSerializer());
private DateTime _sessionStart;
/// <summary>

Просмотреть файл

@ -3026,5 +3026,507 @@ namespace Microsoft.Toolkit.Diagnostics
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotBetweenOrEqualTo(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="target">The target <see langword="nint"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is != <paramref name="target"/>.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsEqualTo(nint value, nint target, string name)
{
if (value == target)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsEqualTo(value, target, name);
}
/// <summary>
/// Asserts that the input value must be not equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="target">The target <see langword="nint"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is == <paramref name="target"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotEqualTo(nint value, nint target, string name)
{
if (value != target)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsNotEqualTo(value, target, name);
}
/// <summary>
/// Asserts that the input value must be less than a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="maximum">The exclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsLessThan(nint value, nint maximum, string name)
{
if (value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsLessThan(value, maximum, name);
}
/// <summary>
/// Asserts that the input value must be less than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="maximum">The inclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsLessThanOrEqualTo(nint value, nint maximum, string name)
{
if (value <= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsLessThanOrEqualTo(value, maximum, name);
}
/// <summary>
/// Asserts that the input value must be greater than a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsGreaterThan(nint value, nint minimum, string name)
{
if (value > minimum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsGreaterThan(value, minimum, name);
}
/// <summary>
/// Asserts that the input value must be greater than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsGreaterThanOrEqualTo(nint value, nint minimum, string name)
{
if (value >= minimum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsGreaterThanOrEqualTo(value, minimum, name);
}
/// <summary>
/// Asserts that the input value must be in a given range.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in [<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsInRange(nint value, nint minimum, nint maximum, string name)
{
if (value >= minimum && value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsInRange(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given range.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in [<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotInRange(nint value, nint minimum, nint maximum, string name)
{
if (value < minimum || value >= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotInRange(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in (<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsBetween(nint value, nint minimum, nint maximum, string name)
{
if (value > minimum && value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsBetween(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in (<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotBetween(nint value, nint minimum, nint maximum, string name)
{
if (value <= minimum || value >= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotBetween(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or > <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in [<paramref name="minimum"/>, <paramref name="maximum"/>]", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsBetweenOrEqualTo(nint value, nint minimum, nint maximum, string name)
{
if (value >= minimum && value <= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsBetweenOrEqualTo(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nint"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see langword="nint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt;= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in [<paramref name="minimum"/>, <paramref name="maximum"/>]", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotBetweenOrEqualTo(nint value, nint minimum, nint maximum, string name)
{
if (value < minimum || value > maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotBetweenOrEqualTo(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="target">The target <see langword="nuint"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is != <paramref name="target"/>.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsEqualTo(nuint value, nuint target, string name)
{
if (value == target)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsEqualTo(value, target, name);
}
/// <summary>
/// Asserts that the input value must be not equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="target">The target <see langword="nuint"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is == <paramref name="target"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotEqualTo(nuint value, nuint target, string name)
{
if (value != target)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsNotEqualTo(value, target, name);
}
/// <summary>
/// Asserts that the input value must be less than a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="maximum">The exclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsLessThan(nuint value, nuint maximum, string name)
{
if (value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsLessThan(value, maximum, name);
}
/// <summary>
/// Asserts that the input value must be less than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="maximum">The inclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsLessThanOrEqualTo(nuint value, nuint maximum, string name)
{
if (value <= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsLessThanOrEqualTo(value, maximum, name);
}
/// <summary>
/// Asserts that the input value must be greater than a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsGreaterThan(nuint value, nuint minimum, string name)
{
if (value > minimum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsGreaterThan(value, minimum, name);
}
/// <summary>
/// Asserts that the input value must be greater than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsGreaterThanOrEqualTo(nuint value, nuint minimum, string name)
{
if (value >= minimum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsGreaterThanOrEqualTo(value, minimum, name);
}
/// <summary>
/// Asserts that the input value must be in a given range.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in [<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsInRange(nuint value, nuint minimum, nuint maximum, string name)
{
if (value >= minimum && value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsInRange(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given range.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in [<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotInRange(nuint value, nuint minimum, nuint maximum, string name)
{
if (value < minimum || value >= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotInRange(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in (<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsBetween(nuint value, nuint minimum, nuint maximum, string name)
{
if (value > minimum && value < maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsBetween(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in (<paramref name="minimum"/>, <paramref name="maximum"/>)", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotBetween(nuint value, nuint minimum, nuint maximum, string name)
{
if (value <= minimum || value >= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotBetween(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or > <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> in [<paramref name="minimum"/>, <paramref name="maximum"/>]", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsBetweenOrEqualTo(nuint value, nuint minimum, nuint maximum, string name)
{
if (value >= minimum && value <= maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsBetweenOrEqualTo(value, minimum, maximum, name);
}
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see langword="nuint"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see langword="nuint"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see langword="nuint"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt;= <paramref name="maximum"/>.</exception>
/// <remarks>
/// This API asserts the equivalent of "<paramref name="value"/> not in [<paramref name="minimum"/>, <paramref name="maximum"/>]", using arithmetic notation.
/// The method is generic to avoid boxing the parameters, if they are value types.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotBetweenOrEqualTo(nuint value, nuint minimum, nuint maximum, string name)
{
if (value < minimum || value > maximum)
{
return;
}
ThrowHelper.ThrowArgumentOutOfRangeExceptionForIsNotBetweenOrEqualTo(value, minimum, maximum, name);
}
}
}

Просмотреть файл

@ -13,14 +13,15 @@ namespace Microsoft.Toolkit.Diagnostics
public static partial class Guard
{
<#
GenerateTextForItems(NumericTypes, type =>
GenerateTextForItems(NumericTypes, typeInfo =>
{
var (type, prefix) = typeInfo;
#>
/// <summary>
/// Asserts that the input value must be equal to a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="target">The target <see cref="<#=type#>"/> value to test for.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="target">The target <see <#=prefix#>="<#=type#>"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is != <paramref name="target"/>.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -37,8 +38,8 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be not equal to a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="target">The target <see cref="<#=type#>"/> value to test for.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="target">The target <see <#=prefix#>="<#=type#>"/> value to test for.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is == <paramref name="target"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
@ -56,8 +57,8 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be less than a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="maximum">The exclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="maximum">The exclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
@ -75,8 +76,8 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be less than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="maximum">The inclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="maximum">The inclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="maximum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
@ -94,8 +95,8 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be greater than a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
@ -113,8 +114,8 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be greater than or equal to a specified value.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/>.</exception>
/// <remarks>The method is generic to avoid boxing the parameters, if they are value types.</remarks>
@ -132,9 +133,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be in a given range.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
@ -155,9 +156,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must not be in a given range.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
@ -178,9 +179,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt;= <paramref name="minimum"/> or >= <paramref name="maximum"/>.</exception>
/// <remarks>
@ -201,9 +202,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The exclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The exclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is > <paramref name="minimum"/> or &lt; <paramref name="maximum"/>.</exception>
/// <remarks>
@ -224,9 +225,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must be in a given interval.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is &lt; <paramref name="minimum"/> or > <paramref name="maximum"/>.</exception>
/// <remarks>
@ -247,9 +248,9 @@ GenerateTextForItems(NumericTypes, type =>
/// <summary>
/// Asserts that the input value must not be in a given interval.
/// </summary>
/// <param name="value">The input <see cref="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see cref="<#=type#>"/> value that is accepted.</param>
/// <param name="value">The input <see <#=prefix#>="<#=type#>"/> value to test.</param>
/// <param name="minimum">The inclusive minimum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="maximum">The inclusive maximum <see <#=prefix#>="<#=type#>"/> value that is accepted.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="value"/> is >= <paramref name="minimum"/> or &lt;= <paramref name="maximum"/>.</exception>
/// <remarks>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,131 +5,125 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class ThrowHelper
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
<#
GenerateTextForItems(EnumerableTypes, item =>
{
#>
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEmpty{T}(T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsEmpty<T>(<#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must be empty, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEmpty{T}(T[],string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsEmpty<T>(<#=item.Type#> <#=item.Name#>, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must be empty, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeNotEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeNotEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size not equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeNotEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeNotEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size not equal to {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeGreaterThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size over {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size over {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeGreaterThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size of at least {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size of at least {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {size}, had a size of {AssertString(<#=item.Name#>.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {destination.<#=item.Size#>.ToAssertString()} (the destination), had a size of {source.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
throw new ArgumentException($"The source {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {AssertString(destination.<#=item.Size#>)} (the destination), had a size of {AssertString(source.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {destination.<#=item.Size#>.ToAssertString()} (the destination), had a size of {source.<#=item.Size#>.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
throw new ArgumentException($"The source {AssertString(name)} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {AssertString(destination.<#=item.Size#>)} (the destination), had a size of {AssertString(source.<#=item.Size#>)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentOutOfRangeException(name, index, $"Parameter {name.ToAssertString()} (int) must be in the range given by <0> and {<#=item.Name#>.<#=item.Size#>.ToAssertString()} to be a valid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {index.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
throw new ArgumentOutOfRangeException(name, index, $"Parameter {AssertString(name)} (int) must be in the range given by <0> and {AssertString(<#=item.Name#>.<#=item.Size#>)} to be a valid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {AssertString(index)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsNotInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentOutOfRangeException(name, index, $"Parameter {name.ToAssertString()} (int) must not be in the range given by <0> and {<#=item.Name#>.<#=item.Size#>.ToAssertString()} to be an invalid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {index.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
throw new ArgumentOutOfRangeException(name, index, $"Parameter {AssertString(name)} (int) must not be in the range given by <0> and {AssertString(<#=item.Name#>.<#=item.Size#>)} to be an invalid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {AssertString(index)}");
}
<#
});
#>
}
}
}

Просмотреть файл

@ -81,7 +81,23 @@
/// <summary>
/// Gets the list of available numeric types to generate APIs for
/// </summary>
static readonly IReadOnlyList<string> NumericTypes = new[] { "byte", "sbyte", "short", "ushort", "char", "int", "uint", "float", "long", "ulong", "double", "decimal" };
static readonly IReadOnlyList<(string Name, string Prefix)> NumericTypes = new[]
{
("byte", "cref"),
("sbyte", "cref"),
("short", "cref"),
("ushort", "cref"),
("char", "cref"),
("int", "cref"),
("uint", "cref"),
("float", "cref"),
("long", "cref"),
("ulong", "cref"),
("double", "cref"),
("decimal", "cref"),
("nint", "langword"),
("nuint", "langword")
};
/// <summary>
/// Generates text for a given sequence of items, automatically adding the necessary spacing

Просмотреть файл

@ -23,18 +23,18 @@ namespace Microsoft.Toolkit.Diagnostics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsCloseTo(int value, int target, uint delta, string name)
{
// Cast to long before calculating the difference to avoid overflows
// when the values are at the two extremes of the supported range.
// Then cast to double to calculate the absolute value: this allows
// the JIT compiler to use AVX instructions on X64 CPUs instead of
// conditional jumps, which results in more efficient assembly code.
// The IEEE 754 specs guarantees that a 32 bit integer value can
// be stored within a double precision floating point value with
// no loss of precision, so the result will always be correct here.
// The difference is then cast to uint as that's the maximum possible
// value it can have, and comparing two 32 bit integer values
// results in shorter and slightly faster code than using doubles.
if ((uint)Math.Abs((double)((long)value - target)) <= delta)
uint difference;
if (value >= target)
{
difference = (uint)(value - target);
}
else
{
difference = (uint)(target - value);
}
if (difference <= delta)
{
return;
}
@ -53,7 +53,18 @@ namespace Microsoft.Toolkit.Diagnostics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotCloseTo(int value, int target, uint delta, string name)
{
if ((uint)Math.Abs((double)((long)value - target)) > delta)
uint difference;
if (value >= target)
{
difference = (uint)(value - target);
}
else
{
difference = (uint)(target - value);
}
if (difference > delta)
{
return;
}
@ -69,12 +80,21 @@ namespace Microsoft.Toolkit.Diagnostics
/// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) > <paramref name="delta"/>.</exception>
[MethodImpl(MethodImplOptions.NoInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsCloseTo(long value, long target, ulong delta, string name)
{
// This method and the one below are not inlined because
// using the decimal type results in quite a bit of code.
if ((ulong)Math.Abs((decimal)value - target) <= delta)
ulong difference;
if (value >= target)
{
difference = (ulong)(value - target);
}
else
{
difference = (ulong)(target - value);
}
if (difference <= delta)
{
return;
}
@ -90,10 +110,21 @@ namespace Microsoft.Toolkit.Diagnostics
/// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) &lt;= <paramref name="delta"/>.</exception>
[MethodImpl(MethodImplOptions.NoInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotCloseTo(long value, long target, ulong delta, string name)
{
if ((ulong)Math.Abs((decimal)value - target) > delta)
ulong difference;
if (value >= target)
{
difference = (ulong)(value - target);
}
else
{
difference = (ulong)(target - value);
}
if (difference > delta)
{
return;
}
@ -176,5 +207,65 @@ namespace Microsoft.Toolkit.Diagnostics
ThrowHelper.ThrowArgumentExceptionForIsNotCloseTo(value, target, delta, name);
}
/// <summary>
/// Asserts that the input value must be within a given distance from a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="target">The target <see langword="nint"/> value to test for.</param>
/// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) > <paramref name="delta"/>.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsCloseTo(nint value, nint target, nuint delta, string name)
{
nuint difference;
if (value >= target)
{
difference = (nuint)(value - target);
}
else
{
difference = (nuint)(target - value);
}
if (difference <= delta)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsCloseTo(value, target, delta, name);
}
/// <summary>
/// Asserts that the input value must not be within a given distance from a specified value.
/// </summary>
/// <param name="value">The input <see langword="nint"/> value to test.</param>
/// <param name="target">The target <see langword="nint"/> value to test for.</param>
/// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param>
/// <param name="name">The name of the input parameter being tested.</param>
/// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) &lt;= <paramref name="delta"/>.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotCloseTo(nint value, nint target, nuint delta, string name)
{
nuint difference;
if (value >= target)
{
difference = (nuint)(value - target);
}
else
{
difference = (nuint)(target - value);
}
if (difference > delta)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsNotCloseTo(value, target, delta, name);
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
// 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.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(Span{T},string)"/> fails.
/// </summary>
/// <typeparam name="T">The item of items in the input <see cref="Span{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="Span{T}"/> can't be used as a generic type parameter.</remarks>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmptyWithSpan<T>(string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(Span<T>).ToTypeString()}) must not be empty", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(ReadOnlySpan{T},string)"/> fails.
/// </summary>
/// <typeparam name="T">The item of items in the input <see cref="ReadOnlySpan{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="ReadOnlySpan{T}"/> can't be used as a generic type parameter.</remarks>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmptyWithReadOnlySpan<T>(string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(ReadOnlySpan<T>).ToTypeString()}) must not be empty", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(T[],string)"/> (or an overload) fails.
/// </summary>
/// <typeparam name="T">The item of items in the input collection.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmpty<T>(string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be empty", name);
}
}
}
}

Просмотреть файл

@ -0,0 +1,175 @@
// 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.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsDefault{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of <see langword="struct"/> value type being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsDefault<T>(T value, string name)
where T : struct
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be the default value {AssertString(default(T))}, was {AssertString(value)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotDefault{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of <see langword="struct"/> value type being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotDefault<T>(string name)
where T : struct
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be the default value {AssertString(default(T))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsEqualTo<T>(T value, T target, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be equal to {AssertString(target)}, was {AssertString(value)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEqualTo<T>(T value, T target, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be equal to {AssertString(target)}, was {AssertString(value)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsBitwiseEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input values being compared.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForBitwiseEqualTo<T>(T value, T target, string name)
where T : unmanaged
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) is not a bitwise match, was <{value.ToHexString()}> instead of <{target.ToHexString()}>", name);
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsLessThan{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsLessThan<T>(T value, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be less than {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsLessThanOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsLessThanOrEqualTo<T>(T value, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be less than or equal to {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsGreaterThan{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsGreaterThan<T>(T value, T minimum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be greater than {AssertString(minimum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsGreaterThanOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsGreaterThanOrEqualTo<T>(T value, T minimum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be greater than or equal to {AssertString(minimum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRange{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsInRange<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be in the range given by {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRange{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotInRange<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be in the range given by {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsBetween{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsBetween<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be between {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotBetween{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotBetween<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be between {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsBetweenOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsBetweenOrEqualTo<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be between or equal to {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotBetweenOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotBetweenOrEqualTo<T>(T value, T minimum, T maximum, string name)
{
throw new ArgumentOutOfRangeException(name, value!, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be between or equal to {AssertString(minimum)} and {AssertString(maximum)}, was {AssertString(value)}");
}
}
}
}

Просмотреть файл

@ -0,0 +1,112 @@
// 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.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(int,int,uint,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCloseTo(int value, int target, uint delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(int).ToTypeString()}) must be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs((double)((long)value - target)))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(int,int,uint,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCloseTo(int value, int target, uint delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(int).ToTypeString()}) must not be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs((double)((long)value - target)))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(long,long,ulong,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCloseTo(long value, long target, ulong delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(long).ToTypeString()}) must be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs((decimal)value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(long,long,ulong,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCloseTo(long value, long target, ulong delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(long).ToTypeString()}) must not be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs((decimal)value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(float,float,float,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCloseTo(float value, float target, float delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(float).ToTypeString()}) must be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(float,float,float,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCloseTo(float value, float target, float delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(float).ToTypeString()}) must not be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(double,double,double,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCloseTo(double value, double target, double delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(double).ToTypeString()}) must be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(double,double,double,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCloseTo(double value, double target, double delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(double).ToTypeString()}) must not be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(nint,nint,nuint,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCloseTo(nint value, nint target, nuint delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(nint).ToTypeString()}) must be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(nint,nint,nuint,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCloseTo(nint value, nint target, nuint delta, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(nint).ToTypeString()}) must not be within a distance of {AssertString(delta)} from {AssertString(target)}, was {AssertString(value)} and had a distance of {AssertString(Math.Abs(value - target))}", name);
}
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
// 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.CodeAnalysis;
using System.IO;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanRead"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForCanRead(Stream stream, string name)
{
throw new ArgumentException($"Stream {AssertString(name)} ({stream.GetType().ToTypeString()}) doesn't support reading", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanWrite"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForCanWrite(Stream stream, string name)
{
throw new ArgumentException($"Stream {AssertString(name)} ({stream.GetType().ToTypeString()}) doesn't support writing", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanSeek"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForCanSeek(Stream stream, string name)
{
throw new ArgumentException($"Stream {AssertString(name)} ({stream.GetType().ToTypeString()}) doesn't support seeking", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAtStartPosition"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsAtStartPosition(Stream stream, string name)
{
throw new ArgumentException($"Stream {AssertString(name)} ({stream.GetType().ToTypeString()}) must be at position {AssertString(0)}, was at {AssertString(stream.Position)}", name);
}
}
}
}

Просмотреть файл

@ -0,0 +1,183 @@
// 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.CodeAnalysis;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNullOrEmpty"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNullOrEmpty(string? text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must be null or empty, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotNullOrEmpty"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotNullOrEmpty(string? text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must not be null or empty, was {(text is null ? "null" : "empty")}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNullOrWhitespace"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNullOrWhiteSpace(string? text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must be null or whitespace, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotNullOrWhitespace"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotNullOrWhiteSpace(string? text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must not be null or whitespace, was {(text is null ? "null" : "whitespace")}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEmpty"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsEmpty(string text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must be empty, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmpty(string text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must not be empty", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsWhitespace"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsWhiteSpace(string text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must be whitespace, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotWhitespace"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotWhiteSpace(string text, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must not be whitespace, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo(string,int,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must have a size equal to {size}, had a size of {text.Length} and was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeNotEqualTo"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeNotEqualTo(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must not have a size equal to {size}, was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThan"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThan(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must have a size over {size}, had a size of {text.Length} and was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThanOrEqualTo"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThanOrEqualTo(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must have a size of at least {size}, had a size of {text.Length} and was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThan"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThan(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must have a size less than {size}, had a size of {text.Length} and was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo(string,int,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo(string text, int size, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} (string) must have a size less than or equal to {size}, had a size of {text.Length} and was {AssertString(text)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo(string,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo(string source, string destination, string name)
{
throw new ArgumentException($"The source {AssertString(name)} (string) must have a size equal to {AssertString(destination.Length)} (the destination), had a size of {AssertString(source.Length)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo(string,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo(string source, string destination, string name)
{
throw new ArgumentException($"The source {AssertString(name)} (string) must have a size less than or equal to {AssertString(destination.Length)} (the destination), had a size of {AssertString(source.Length)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRangeFor(int,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsInRangeFor(int index, string text, string name)
{
throw new ArgumentOutOfRangeException(name, index, $"Parameter {AssertString(name)} (int) must be in the range given by <0> and {AssertString(text.Length)} to be a valid index for the target string, was {AssertString(index)}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotInRangeFor(int,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotInRangeFor(int index, string text, string name)
{
throw new ArgumentOutOfRangeException(name, index, $"Parameter {AssertString(name)} (int) must not be in the range given by <0> and {AssertString(text.Length)} to be an invalid index for the target string, was {AssertString(index)}");
}
}
}
}

Просмотреть файл

@ -0,0 +1,113 @@
// 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.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCompleted"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCompleted(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must be completed, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCompleted"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCompleted(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must not be completed, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCompletedSuccessfully"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCompletedSuccessfully(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must be completed successfully, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCompletedSuccessfully"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCompletedSuccessfully(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must not be completed successfully, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFaulted"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsFaulted(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must be faulted, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotFaulted"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotFaulted(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must not be faulted, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCanceled"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsCanceled(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must be canceled, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCanceled"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotCanceled(Task task, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must not be canceled, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasStatusEqualTo"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasStatusEqualTo(Task task, TaskStatus status, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must have status {status}, had status {AssertString(task.Status)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasStatusNotEqualTo"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasStatusNotEqualTo(Task task, TaskStatus status, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} ({task.GetType().ToTypeString()}) must not have status {AssertString(status)}", name);
}
}
}
}

Просмотреть файл

@ -0,0 +1,205 @@
// 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.CodeAnalysis;
using System.Diagnostics.Contracts;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to verify conditions when running code.
/// </summary>
public static partial class Guard
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
private static partial class ThrowHelper
{
/// <summary>
/// Returns a formatted representation of the input value.
/// </summary>
/// <param name="obj">The input <see cref="object"/> to format.</param>
/// <returns>A formatted representation of <paramref name="obj"/> to display in error messages.</returns>
[Pure]
private static string AssertString(object? obj)
{
return obj switch
{
string _ => $"\"{obj}\"",
null => "null",
_ => $"<{obj}>"
};
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNull{T}(T,string)"/> (where <typeparamref name="T"/> is <see langword="class"/>) fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNull<T>(T value, string name)
where T : class
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be null, was {AssertString(value)} ({value.GetType().ToTypeString()})", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNull{T}(T,string)"/> (where <typeparamref name="T"/> is <see langword="struct"/>) fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNull<T>(T? value, string name)
where T : struct
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T?).ToTypeString()}) must be null, was {AssertString(value)} ({typeof(T).ToTypeString()})", name);
}
/// <summary>
/// Throws an <see cref="ArgumentNullException"/> when <see cref="Guard.IsNotNull{T}(T,string)"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentNullExceptionForIsNotNull<T>(string name)
{
throw new ArgumentNullException(name, $"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be not null)");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsOfType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsOfType<T>(object value, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be of type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotOfType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotOfType<T>(object value, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must not be of type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsOfType"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsOfType(object value, Type type, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be of type {type.ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotOfType"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotOfType(object value, Type type, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must not be of type {type.ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type being checked against.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsAssignableToType<T>(object value, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be assignable to type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotAssignableToType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type being checked against.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotAssignableToType<T>(object value, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must not be assignable to type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsAssignableToType(object value, Type type, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be assignable to type {type.ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotAssignableToType(object value, Type type, string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must not be assignable to type {type.ToTypeString()}, was {value.GetType().ToTypeString()}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsReferenceEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input value being compared.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsReferenceEqualTo<T>(string name)
where T : class
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must be the same instance as the target object", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsReferenceNotEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input value being compared.</typeparam>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsReferenceNotEqualTo<T>(string name)
where T : class
{
throw new ArgumentException($"Parameter {AssertString(name)} ({typeof(T).ToTypeString()}) must not be the same instance as the target object", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsTrue(bool,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsTrue(string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be true, was false", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsTrue(bool,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsTrue(string name, string message)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be true, was false: {AssertString(message)}", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFalse(bool,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsFalse(string name)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be false, was true", name);
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFalse(bool,string,string)"/> fails.
/// </summary>
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsFalse(string name, string message)
{
throw new ArgumentException($"Parameter {AssertString(name)} must be false, was true: {AssertString(message)}", name);
}
}
}
}

Просмотреть файл

@ -1,52 +0,0 @@
// 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.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(Span{T},string)"/> fails.
/// </summary>
/// <typeparam name="T">The item of items in the input <see cref="Span{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="Span{T}"/> can't be used as a generic type parameter.</remarks>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotEmptyWithSpan<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(Span<T>).ToTypeString()}) must not be empty");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(ReadOnlySpan{T},string)"/> fails.
/// </summary>
/// <typeparam name="T">The item of items in the input <see cref="ReadOnlySpan{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="ReadOnlySpan{T}"/> can't be used as a generic type parameter.</remarks>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotEmptyWithReadOnlySpan<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(ReadOnlySpan<T>).ToTypeString()}) must not be empty");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty{T}(T[],string)"/> (or an overload) fails.
/// </summary>
/// <typeparam name="T">The item of items in the input collection.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotEmpty<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be empty");
}
}
}

Просмотреть файл

@ -1,185 +0,0 @@
// 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.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsDefault{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of <see langword="struct"/> value type being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsDefault<T>(T value, string name)
where T : struct
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be the default value {default(T).ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotDefault{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of <see langword="struct"/> value type being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotDefault<T>(string name)
where T : struct
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be the default value {default(T).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsEqualTo<T>(T value, T target, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be equal to {target.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotEqualTo<T>(T value, T target, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be equal to {target.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsBitwiseEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input values being compared.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForBitwiseEqualTo<T>(T value, T target, string name)
where T : unmanaged
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) is not a bitwise match, was <{value.ToHexString()}> instead of <{target.ToHexString()}>");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsLessThan{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsLessThan<T>(T value, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be less than {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsLessThanOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsLessThanOrEqualTo<T>(T value, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be less than or equal to {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsGreaterThan{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsGreaterThan<T>(T value, T minimum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be greater than {minimum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsGreaterThanOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsGreaterThanOrEqualTo<T>(T value, T minimum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be greater than or equal to {minimum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRange{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsInRange<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be in the range given by {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRange{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsNotInRange<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be in the range given by {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsBetween{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsBetween<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be between {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotBetween{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsNotBetween<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be between {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsBetweenOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsBetweenOrEqualTo<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be between or equal to {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotBetweenOrEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of values being tested.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsNotBetweenOrEqualTo<T>(T value, T minimum, T maximum, string name)
{
ThrowArgumentOutOfRangeException(name, value!, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be between or equal to {minimum.ToAssertString()} and {maximum.ToAssertString()}, was {value.ToAssertString()}");
}
}
}

Просмотреть файл

@ -1,97 +0,0 @@
// 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.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(int,int,uint,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCloseTo(int value, int target, uint delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(int).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((double)((long)value - target)).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(int,int,uint,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCloseTo(int value, int target, uint delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(int).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((double)((long)value - target)).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(long,long,ulong,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCloseTo(long value, long target, ulong delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(long).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((decimal)value - target).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(long,long,ulong,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCloseTo(long value, long target, ulong delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(long).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((decimal)value - target).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(float,float,float,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCloseTo(float value, float target, float delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(float).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(float,float,float,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCloseTo(float value, float target, float delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(float).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(double,double,double,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCloseTo(double value, double target, double delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(double).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(double,double,double,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCloseTo(double value, double target, double delta, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(double).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}");
}
}
}

Просмотреть файл

@ -1,58 +0,0 @@
// 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.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanRead"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForCanRead(Stream stream, string name)
{
ThrowArgumentException(name, $"Stream {name.ToAssertString()} ({stream.GetType().ToTypeString()}) doesn't support reading");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanWrite"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForCanWrite(Stream stream, string name)
{
ThrowArgumentException(name, $"Stream {name.ToAssertString()} ({stream.GetType().ToTypeString()}) doesn't support writing");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.CanSeek"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForCanSeek(Stream stream, string name)
{
ThrowArgumentException(name, $"Stream {name.ToAssertString()} ({stream.GetType().ToTypeString()}) doesn't support seeking");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAtStartPosition"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsAtStartPosition(Stream stream, string name)
{
ThrowArgumentException(name, $"Stream {name.ToAssertString()} ({stream.GetType().ToTypeString()}) must be at position {0.ToAssertString()}, was at {stream.Position.ToAssertString()}");
}
}
}

Просмотреть файл

@ -1,196 +0,0 @@
// 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.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNullOrEmpty"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNullOrEmpty(string? text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must be null or empty, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotNullOrEmpty"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotNullOrEmpty(string? text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must not be null or empty, was {(text is null ? "null" : "empty")}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNullOrWhitespace"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNullOrWhiteSpace(string? text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must be null or whitespace, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotNullOrWhitespace"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotNullOrWhiteSpace(string? text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must not be null or whitespace, was {(text is null ? "null" : "whitespace")}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEmpty"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsEmpty(string text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must be empty, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotEmpty"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotEmpty(string text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must not be empty");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsWhitespace"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsWhiteSpace(string text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must be whitespace, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotWhitespace"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotWhiteSpace(string text, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must not be whitespace, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo(string,int,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeEqualTo(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must have a size equal to {size}, had a size of {text.Length} and was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeNotEqualTo"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeNotEqualTo(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must not have a size equal to {size}, was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThan"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeGreaterThan(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must have a size over {size}, had a size of {text.Length} and was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThanOrEqualTo"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeGreaterThanOrEqualTo(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must have a size of at least {size}, had a size of {text.Length} and was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThan"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThan(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must have a size less than {size}, had a size of {text.Length} and was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo(string,int,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo(string text, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} (string) must have a size less than or equal to {size}, had a size of {text.Length} and was {text.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo(string,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeEqualTo(string source, string destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} (string) must have a size equal to {destination.Length.ToAssertString()} (the destination), had a size of {source.Length.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo(string,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo(string source, string destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} (string) must have a size less than or equal to {destination.Length.ToAssertString()} (the destination), had a size of {source.Length.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRangeFor(int,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsInRangeFor(int index, string text, string name)
{
ThrowArgumentOutOfRangeException(name, index, $"Parameter {name.ToAssertString()} (int) must be in the range given by <0> and {text.Length.ToAssertString()} to be a valid index for the target string, was {index.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotInRangeFor(int,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeExceptionForIsNotInRangeFor(int index, string text, string name)
{
ThrowArgumentOutOfRangeException(name, index, $"Parameter {name.ToAssertString()} (int) must not be in the range given by <0> and {text.Length.ToAssertString()} to be an invalid index for the target string, was {index.ToAssertString()}");
}
}
}

Просмотреть файл

@ -1,118 +0,0 @@
// 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.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCompleted"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCompleted(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must be completed, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCompleted"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCompleted(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must not be completed, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCompletedSuccessfully"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCompletedSuccessfully(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must be completed successfully, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCompletedSuccessfully"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCompletedSuccessfully(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must not be completed successfully, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFaulted"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsFaulted(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must be faulted, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotFaulted"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotFaulted(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must not be faulted, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCanceled"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsCanceled(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must be canceled, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCanceled"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotCanceled(Task task, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must not be canceled, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasStatusEqualTo"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasStatusEqualTo(Task task, TaskStatus status, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must have status {status}, had status {task.Status.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasStatusNotEqualTo"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForHasStatusNotEqualTo(Task task, TaskStatus status, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({task.GetType().ToTypeString()}) must not have status {status.ToAssertString()}");
}
}
}

Просмотреть файл

@ -1,217 +0,0 @@
// 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.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
public static partial class ThrowHelper
{
/// <summary>
/// Returns a formatted representation of the input value.
/// </summary>
/// <param name="obj">The input <see cref="object"/> to format.</param>
/// <returns>A formatted representation of <paramref name="obj"/> to display in error messages.</returns>
[Pure]
private static string ToAssertString(this object? obj)
{
return obj switch
{
string _ => $"\"{obj}\"",
null => "null",
_ => $"<{obj}>"
};
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNull{T}(T,string)"/> (where <typeparamref name="T"/> is <see langword="class"/>) fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNull<T>(T value, string name)
where T : class
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be null, was {value.ToAssertString()} ({value.GetType().ToTypeString()})");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNull{T}(T,string)"/> (where <typeparamref name="T"/> is <see langword="struct"/>) fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNull<T>(T? value, string name)
where T : struct
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T?).ToTypeString()}) must be null, was {value.ToAssertString()} ({typeof(T).ToTypeString()})");
}
/// <summary>
/// Throws an <see cref="ArgumentNullException"/> when <see cref="Guard.IsNotNull{T}(T,string)"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentNullExceptionForIsNotNull<T>(string name)
{
ThrowArgumentNullException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be not null)");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsOfType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsOfType<T>(object value, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be of type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotOfType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of the input value.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotOfType<T>(object value, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must not be of type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsOfType"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsOfType(object value, Type type, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be of type {type.ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotOfType"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotOfType(object value, Type type, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must not be of type {type.ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type being checked against.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsAssignableToType<T>(object value, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be assignable to type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotAssignableToType{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type being checked against.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotAssignableToType<T>(object value, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must not be assignable to type {typeof(T).ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsAssignableToType(object value, Type type, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be assignable to type {type.ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsAssignableToType"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsNotAssignableToType(object value, Type type, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must not be assignable to type {type.ToTypeString()}, was {value.GetType().ToTypeString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsReferenceEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input value being compared.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsReferenceEqualTo<T>(string name)
where T : class
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must be the same instance as the target object");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsReferenceNotEqualTo{T}"/> fails.
/// </summary>
/// <typeparam name="T">The type of input value being compared.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsReferenceNotEqualTo<T>(string name)
where T : class
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be the same instance as the target object");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsTrue(bool,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsTrue(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be true, was false");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsTrue(bool,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsTrue(string name, string message)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be true, was false: {message.ToAssertString()}");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFalse(bool,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsFalse(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be false, was true");
}
/// <summary>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsFalse(bool,string,string)"/> fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
internal static void ThrowArgumentExceptionForIsFalse(string name, string message)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} must be false, was true: {message.ToAssertString()}");
}
}
}

Просмотреть файл

@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@ -13,88 +12,102 @@ namespace UnitTests.Diagnostics
{
[TestCategory("Guard")]
[TestMethod]
public void Test_Guard_IsCloseToInt_Ok()
[DataRow(0, 20, 10u, false)]
[DataRow(0, 6, 5u, false)]
[DataRow(0, int.MaxValue, 500u, false)]
[DataRow(-500, -530, 10u, false)]
[DataRow(1000, 800, 100u, false)]
[DataRow(int.MaxValue, int.MaxValue - 10, 7u, false)]
[DataRow(int.MinValue, int.MaxValue, (uint)int.MaxValue, false)]
[DataRow(0, 5, 10u, true)]
[DataRow(0, 5, 5u, true)]
[DataRow(0, int.MaxValue, (uint)int.MaxValue, true)]
[DataRow(-500, -530, 50u, true)]
[DataRow(1000, 800, 200u, true)]
[DataRow(int.MaxValue, int.MaxValue - 10, 10u, true)]
public void Test_Guard_IsCloseOrNotToInt(int value, int target, uint delta, bool isClose)
{
Guard.IsCloseTo(0, 5, 10, nameof(Test_Guard_IsCloseToInt_Ok));
Guard.IsCloseTo(0, 5, 5, nameof(Test_Guard_IsCloseToInt_Ok));
Guard.IsCloseTo(0, int.MaxValue, int.MaxValue, nameof(Test_Guard_IsCloseToInt_Ok));
Guard.IsCloseTo(-500, -530, 50, nameof(Test_Guard_IsCloseToInt_Ok));
Guard.IsCloseTo(1000, 800, 200, nameof(Test_Guard_IsCloseToInt_Ok));
Guard.IsCloseTo(int.MaxValue, int.MaxValue - 10, 10, nameof(Test_Guard_IsCloseToInt_Ok));
}
[TestCategory("Guard")]
[TestMethod]
[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000", Justification = "Value tuple")]
public void Test_Guard_IsCloseToInt_Fail()
{
foreach (var item in new (int Value, int Target, uint Delta)[]
void Test(int value, int target)
{
(0, 20, 10),
(0, 6, 5),
(0, int.MaxValue, 500),
(-500, -530, 10),
(1000, 800, 100),
(int.MaxValue, int.MaxValue - 10, 7),
(int.MinValue, int.MaxValue, int.MaxValue)
})
{
bool fail = false;
bool isFailed = false;
try
{
Guard.IsCloseTo(item.Value, item.Target, item.Delta, nameof(Test_Guard_IsCloseToInt_Fail));
Guard.IsCloseTo(value, target, delta, nameof(Test_Guard_IsCloseOrNotToInt));
}
catch (ArgumentException)
{
fail = true;
isFailed = true;
}
Assert.IsTrue(fail, $"IsCloseTo didn't fail with {item}");
}
}
Assert.AreEqual(isClose, !isFailed);
[TestCategory("Guard")]
[TestMethod]
public void Test_Guard_IsCloseToFloat_Ok()
{
Guard.IsCloseTo(0f, 5, 10, nameof(Test_Guard_IsCloseToFloat_Ok));
Guard.IsCloseTo(0f, 5, 5, nameof(Test_Guard_IsCloseToFloat_Ok));
Guard.IsCloseTo(0f, float.MaxValue, float.MaxValue, nameof(Test_Guard_IsCloseToFloat_Ok));
Guard.IsCloseTo(-500f, -530, 50, nameof(Test_Guard_IsCloseToFloat_Ok));
Guard.IsCloseTo(1000f, 800, 200, nameof(Test_Guard_IsCloseToFloat_Ok));
Guard.IsCloseTo(float.MaxValue, float.MaxValue - 10, 10, nameof(Test_Guard_IsCloseToFloat_Ok));
}
[TestCategory("Guard")]
[TestMethod]
[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000", Justification = "Value tuple")]
public void Test_Guard_IsCloseToFloat_Fail()
{
foreach (var item in new (float Value, float Target, float Delta)[]
{
(0, 20, 10),
(0, 6, 5),
(0, float.MaxValue, 500),
(-500, -530, 10),
(1000, 800, 100),
(float.MaxValue, float.MaxValue / 2, 7),
(float.MinValue, float.MaxValue, float.MaxValue)
})
{
bool fail = false;
isFailed = false;
try
{
Guard.IsCloseTo(item.Value, item.Target, item.Delta, nameof(Test_Guard_IsCloseToFloat_Fail));
Guard.IsNotCloseTo(value, target, delta, nameof(Test_Guard_IsCloseOrNotToInt));
}
catch (ArgumentException)
{
fail = true;
isFailed = true;
}
Assert.IsTrue(fail, $"IsCloseTo didn't fail with {item}");
Assert.AreEqual(isClose, isFailed);
}
Test(value, target);
Test(target, value);
}
[TestCategory("Guard")]
[TestMethod]
[DataRow(0f, 20f, 10f, false)]
[DataRow(0f, 6f, 5f, false)]
[DataRow(0f, float.MaxValue, 500f, false)]
[DataRow(-500f, -530f, 10f, false)]
[DataRow(1000f, 800f, 100f, false)]
[DataRow(float.MaxValue, float.MaxValue / 2, 7f, false)]
[DataRow(float.MinValue, float.MaxValue, float.MaxValue, false)]
[DataRow(0f, 5f, 10f, true)]
[DataRow(0f, 5f, 5f, true)]
[DataRow(0f, float.MaxValue, float.MaxValue, true)]
[DataRow(-500f, -530f, 50f, true)]
[DataRow(1000f, 800f, 200f, true)]
[DataRow(float.MaxValue, float.MaxValue - 10, 10f, true)]
public void Test_Guard_IsCloseToFloat(float value, float target, float delta, bool isClose)
{
void Test(float value, float target)
{
bool isFailed = false;
try
{
Guard.IsCloseTo(value, target, delta, nameof(Test_Guard_IsCloseToFloat));
}
catch (ArgumentException)
{
isFailed = true;
}
Assert.AreEqual(isClose, !isFailed);
isFailed = false;
try
{
Guard.IsNotCloseTo(value, target, delta, nameof(Test_Guard_IsCloseToFloat));
}
catch (ArgumentException)
{
isFailed = true;
}
Assert.AreEqual(isClose, isFailed);
}
Test(value, target);
Test(target, value);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
// 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.Reflection;
using Microsoft.Toolkit.Uwp.Helpers;
using Newtonsoft.Json;
namespace UnitTests.UWP.Helpers
{
/// <summary>
/// This is a Serializer which should mimic the previous functionality of 6.1.1 release of the Toolkit with Newtonsoft.Json.
/// </summary>
internal class JsonObjectSerializer : IObjectSerializer
{
public T Deserialize<T>(object value)
{
var type = typeof(T);
var typeInfo = type.GetTypeInfo();
// Note: If you're creating a new app, you could just use the serializer directly.
// This if/return combo is to maintain compatibility with 6.1.1
if (typeInfo.IsPrimitive || type == typeof(string))
{
return (T)Convert.ChangeType(value, type);
}
return JsonConvert.DeserializeObject<T>((string)value);
}
public object Serialize<T>(T value)
{
var type = typeof(T);
var typeInfo = type.GetTypeInfo();
// Note: If you're creating a new app, you could just use the serializer directly.
// This if/return combo is to maintain compatibility with 6.1.1
if (typeInfo.IsPrimitive || type == typeof(string))
{
return value;
}
return JsonConvert.SerializeObject(value);
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
// 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.Text.Json;
using Microsoft.Toolkit.Uwp.Helpers;
namespace UnitTests.UWP.Helpers
{
/// <summary>
/// Example class of writing a new <see cref="IObjectSerializer"/> that uses System.Text.Json.
/// </summary>
internal class SystemTextJsonSerializer : IObjectSerializer
{
public T Deserialize<T>(object value) => JsonSerializer.Deserialize<T>(value as string);
public object Serialize<T>(T value) => JsonSerializer.Serialize(value);
}
}

Просмотреть файл

@ -2,18 +2,35 @@
// 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 Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text.Json;
using UnitTests.UI;
using Newtonsoft.Json;
using UnitTests.UWP.Helpers;
using Windows.Storage;
namespace UnitTests.Helpers
{
[TestClass]
public class Test_StorageHelper
{
private LocalObjectStorageHelper storageHelper = new LocalObjectStorageHelper();
private LocalObjectStorageHelper _localStorageHelperSystem = new LocalObjectStorageHelper(new SystemSerializer());
private LocalObjectStorageHelper _localStorageHelperJsonCompat = new LocalObjectStorageHelper(new JsonObjectSerializer());
private LocalObjectStorageHelper _localStorageHelperJsonNew = new LocalObjectStorageHelper(new SystemTextJsonSerializer());
/// <summary>
/// Checks that we're running 10.0.3 version of Newtonsoft.Json package which we used in 6.1.1.
/// </summary>
[TestCategory("Helpers")]
[TestMethod]
public void Test_StorageHelper_CheckNewtonsoftVersion()
{
var version = typeof(JsonSerializer).Assembly.GetName().Version;
Assert.AreEqual(10, version.Major);
Assert.AreEqual(0, version.Minor);
Assert.AreEqual(0, version.Revision); // Apparently the file revision was not updated for the updated package
}
[TestCategory("Helpers")]
[TestMethod]
@ -23,38 +40,57 @@ namespace UnitTests.Helpers
int input = 42;
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonSerializer.Serialize(input);
// Use our previous Json layer to store value
_localStorageHelperJsonCompat.Save(key, input);
storageHelper.Save<string>(key, jsonInput);
// now read it as int to valid that the change works
int output = storageHelper.Read<int>(key, 0);
// But try and read from our new system to see if it works
int output = _localStorageHelperSystem.Read(key, 0);
Assert.AreEqual(input, output);
}
[Ignore]
/// <summary>
/// If we try and deserialize a complex type with the <see cref="SystemSerializer"/>, we do a check ourselves and will throw our own exception.
/// </summary>
[TestCategory("Helpers")]
[TestMethod]
public void Test_StorageHelper_LegacyDateTest()
[ExpectedException(typeof(NotSupportedException))]
public void Test_StorageHelper_LegacyDateTestFailure()
{
string key = "ChristmasDay";
DateTime input = new DateTime(2017, 12, 25);
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save<string>(key, jsonInput);
_localStorageHelperJsonCompat.Save(key, input);
// now read it as int to valid that the change works
DateTime output = storageHelper.Read<DateTime>(key, DateTime.Today);
Assert.AreEqual(input, output);
DateTime output = _localStorageHelperSystem.Read(key, DateTime.Today);
}
/// <summary>
/// The <see cref="SystemSerializer"/> doesn't support complex types, since it just passes through directly.
/// We'll get the argument exception from the <see cref="ApplicationDataContainer"/> API.
/// </summary>
[TestCategory("Helpers")]
[TestMethod]
public void Test_StorageHelper_DateTestFailure()
{
Exception expectedException = null;
// We can't use standard exception checking here like Assert.Throws or ExpectedException
// as local and online platforms seem to throw different exception types :(
try
{
_localStorageHelperSystem.Save("Today", DateTime.Today);
}
catch (Exception exception)
{
expectedException = exception;
}
Assert.IsNotNull(expectedException, "Was expecting an Exception.");
}
[Ignore]
[TestCategory("Helpers")]
[TestMethod]
public void Test_StorageHelper_LegacyInternalClassTest()
@ -64,12 +100,10 @@ namespace UnitTests.Helpers
UI.Person input = new UI.Person() { Name = "Joe Bloggs", Age = 42 };
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save<string>(key, jsonInput);
_localStorageHelperJsonCompat.Save(key, input);
// now read it as int to valid that the change works
UI.Person output = storageHelper.Read<UI.Person>(key, null);
UI.Person output = _localStorageHelperJsonCompat.Read<UI.Person>(key, null);
Assert.IsNotNull(output);
Assert.AreEqual(input.Name, output.Name);
@ -82,15 +116,14 @@ namespace UnitTests.Helpers
{
string key = "Contact";
// Here's we're serializing a different class which has the same properties as our other class below.
UI.Person input = new UI.Person() { Name = "Joe Bloggs", Age = 42 };
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save(key, jsonInput);
_localStorageHelperJsonCompat.Save(key, input);
// now read it as int to valid that the change works
Person output = storageHelper.Read<Person>(key, null);
Person output = _localStorageHelperJsonCompat.Read<Person>(key, null);
Assert.IsNotNull(output);
Assert.AreEqual(input.Name, output.Name);
@ -105,10 +138,10 @@ namespace UnitTests.Helpers
int input = 42;
storageHelper.Save<int>(key, input);
_localStorageHelperSystem.Save<int>(key, input);
// now read it as int to valid that the change works
int output = storageHelper.Read<int>(key, 0);
int output = _localStorageHelperSystem.Read<int>(key, 0);
Assert.AreEqual(input, output);
}
@ -121,10 +154,10 @@ namespace UnitTests.Helpers
DateTime input = new DateTime(2017, 12, 25);
storageHelper.Save<DateTime>(key, input);
_localStorageHelperJsonNew.Save(key, input);
// now read it as int to valid that the change works
DateTime output = storageHelper.Read<DateTime>(key, DateTime.Today);
DateTime output = _localStorageHelperJsonNew.Read(key, DateTime.Today);
Assert.AreEqual(input, output);
}
@ -137,10 +170,10 @@ namespace UnitTests.Helpers
Person input = new Person() { Name = "Joe Bloggs", Age = 42 };
storageHelper.Save<Person>(key, input);
_localStorageHelperJsonNew.Save(key, input);
// now read it as int to valid that the change works
Person output = storageHelper.Read<Person>(key, null);
Person output = _localStorageHelperJsonNew.Read<Person>(key, null);
Assert.IsNotNull(output);
Assert.AreEqual(input.Name, output.Name);

Просмотреть файл

@ -119,6 +119,13 @@
<PackageReference Include="MSTest.TestFramework">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>10.0.3</Version>
<!-- DO NOT UPGRADE THIS PACKAGE FROM 10.0.3, this is used for upgrade testing between 6.1.1 and 7.0.0 for the Object Serializers -->
</PackageReference>
<PackageReference Include="System.Text.Json">
<Version>4.7.2</Version>
</PackageReference>
<PackageReference Include="System.Xml.XPath.XmlDocument">
<Version>4.3.0</Version>
</PackageReference>
@ -141,6 +148,8 @@
<Compile Include="Extensions\Test_EnumValuesExtension.cs" />
<Compile Include="Extensions\Test_NullableBoolMarkupExtension.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Helpers\JsonObjectSerializer.cs" />
<Compile Include="Helpers\SystemTextJsonSerializer.cs" />
<Compile Include="Helpers\TestCollectionCapableDeepLinkParser.cs" />
<Compile Include="Helpers\TestDeepLinkParser.cs" />
<Compile Include="Extensions\Test_DispatcherQueueExtensions.cs" />