diff --git a/Microsoft.Toolkit/Attributes/DoesNotReturnAttribute.cs b/Microsoft.Toolkit.Diagnostics/Attributes/DoesNotReturnAttribute.cs
similarity index 100%
rename from Microsoft.Toolkit/Attributes/DoesNotReturnAttribute.cs
rename to Microsoft.Toolkit.Diagnostics/Attributes/DoesNotReturnAttribute.cs
diff --git a/Microsoft.Toolkit/Attributes/DoesNotReturnIfAttribute.cs b/Microsoft.Toolkit.Diagnostics/Attributes/DoesNotReturnIfAttribute.cs
similarity index 100%
rename from Microsoft.Toolkit/Attributes/DoesNotReturnIfAttribute.cs
rename to Microsoft.Toolkit.Diagnostics/Attributes/DoesNotReturnIfAttribute.cs
diff --git a/Microsoft.Toolkit/Attributes/NotNullAttribute.cs b/Microsoft.Toolkit.Diagnostics/Attributes/NotNullAttribute.cs
similarity index 100%
rename from Microsoft.Toolkit/Attributes/NotNullAttribute.cs
rename to Microsoft.Toolkit.Diagnostics/Attributes/NotNullAttribute.cs
diff --git a/Microsoft.Toolkit/Attributes/SkipLocalsInitAttribute.cs b/Microsoft.Toolkit.Diagnostics/Attributes/SkipLocalsInitAttribute.cs
similarity index 100%
rename from Microsoft.Toolkit/Attributes/SkipLocalsInitAttribute.cs
rename to Microsoft.Toolkit.Diagnostics/Attributes/SkipLocalsInitAttribute.cs
diff --git a/Microsoft.Toolkit/Extensions/TypeExtensions.cs b/Microsoft.Toolkit.Diagnostics/Extensions/TypeExtensions.cs
similarity index 100%
rename from Microsoft.Toolkit/Extensions/TypeExtensions.cs
rename to Microsoft.Toolkit.Diagnostics/Extensions/TypeExtensions.cs
diff --git a/Microsoft.Toolkit/Extensions/ValueTypeExtensions.cs b/Microsoft.Toolkit.Diagnostics/Extensions/ValueTypeExtensions.cs
similarity index 100%
rename from Microsoft.Toolkit/Extensions/ValueTypeExtensions.cs
rename to Microsoft.Toolkit.Diagnostics/Extensions/ValueTypeExtensions.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/Guard.Collection.g.cs b/Microsoft.Toolkit.Diagnostics/Generated/Guard.Collection.g.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/Guard.Collection.g.cs
rename to Microsoft.Toolkit.Diagnostics/Generated/Guard.Collection.g.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/Guard.Collection.tt b/Microsoft.Toolkit.Diagnostics/Generated/Guard.Collection.tt
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/Guard.Collection.tt
rename to Microsoft.Toolkit.Diagnostics/Generated/Guard.Collection.tt
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/Guard.Comparable.Numeric.g.cs b/Microsoft.Toolkit.Diagnostics/Generated/Guard.Comparable.Numeric.g.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/Guard.Comparable.Numeric.g.cs
rename to Microsoft.Toolkit.Diagnostics/Generated/Guard.Comparable.Numeric.g.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/Guard.Comparable.Numeric.tt b/Microsoft.Toolkit.Diagnostics/Generated/Guard.Comparable.Numeric.tt
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/Guard.Comparable.Numeric.tt
rename to Microsoft.Toolkit.Diagnostics/Generated/Guard.Comparable.Numeric.tt
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/Guard.md b/Microsoft.Toolkit.Diagnostics/Generated/Guard.md
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/Guard.md
rename to Microsoft.Toolkit.Diagnostics/Generated/Guard.md
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/ThrowHelper.Collection.g.cs b/Microsoft.Toolkit.Diagnostics/Generated/ThrowHelper.Collection.g.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/ThrowHelper.Collection.g.cs
rename to Microsoft.Toolkit.Diagnostics/Generated/ThrowHelper.Collection.g.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/ThrowHelper.Collection.tt b/Microsoft.Toolkit.Diagnostics/Generated/ThrowHelper.Collection.tt
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/ThrowHelper.Collection.tt
rename to Microsoft.Toolkit.Diagnostics/Generated/ThrowHelper.Collection.tt
diff --git a/Microsoft.Toolkit/Diagnostics/Generated/TypeInfo.ttinclude b/Microsoft.Toolkit.Diagnostics/Generated/TypeInfo.ttinclude
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Generated/TypeInfo.ttinclude
rename to Microsoft.Toolkit.Diagnostics/Generated/TypeInfo.ttinclude
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.Comparable.Generic.cs b/Microsoft.Toolkit.Diagnostics/Guard.Comparable.Generic.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.Comparable.Generic.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.Comparable.Generic.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.Comparable.Numeric.cs b/Microsoft.Toolkit.Diagnostics/Guard.Comparable.Numeric.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.Comparable.Numeric.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.Comparable.Numeric.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.IO.cs b/Microsoft.Toolkit.Diagnostics/Guard.IO.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.IO.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.IO.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.String.cs b/Microsoft.Toolkit.Diagnostics/Guard.String.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.String.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.String.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.Tasks.cs b/Microsoft.Toolkit.Diagnostics/Guard.Tasks.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.Tasks.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.Tasks.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Guard.cs b/Microsoft.Toolkit.Diagnostics/Guard.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Guard.cs
rename to Microsoft.Toolkit.Diagnostics/Guard.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.Collection.Generic.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.Collection.Generic.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.Collection.Generic.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.Collection.Generic.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.Comparable.Generic.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.Comparable.Generic.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.Comparable.Generic.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.Comparable.Generic.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.Comparable.Numeric.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.Comparable.Numeric.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.Comparable.Numeric.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.Comparable.Numeric.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.IO.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.IO.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.IO.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.IO.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.String.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.String.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.String.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.String.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.Tasks.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.Tasks.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.Tasks.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.Tasks.ThrowHelper.cs
diff --git a/Microsoft.Toolkit/Diagnostics/Internals/Guard.ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/Internals/Guard.ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/Internals/Guard.ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/Internals/Guard.ThrowHelper.cs
diff --git a/Microsoft.Toolkit.Diagnostics/Microsoft.Toolkit.Diagnostics.csproj b/Microsoft.Toolkit.Diagnostics/Microsoft.Toolkit.Diagnostics.csproj
new file mode 100644
index 00000000000..4d541b559e3
--- /dev/null
+++ b/Microsoft.Toolkit.Diagnostics/Microsoft.Toolkit.Diagnostics.csproj
@@ -0,0 +1,97 @@
+
+
+
+ netstandard1.4;netstandard2.0;netstandard2.1;net5.0
+ 9.0
+ true
+ enable
+ Windows Community Toolkit Diagnostics .NET Standard
+
+ This package includes .NET Standard code only helpers such as:
+ - Guard: Helper methods to verify conditions when running code.
+ - ThrowHelper: Helper methods to efficiently throw exceptions.
+
+ UWP Toolkit Windows IncrementalLoadingCollection String Array extensions helpers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NETSTANDARD2_1_OR_GREATER
+
+
+
+
+
+
+
+
+
+ NETSTANDARD2_1_OR_GREATER
+
+
+
+
+
+
+ TextTemplatingFileGenerator
+ Guard.Comparable.Numeric.g.cs
+
+
+ TextTemplatingFileGenerator
+ Guard.Collection.g.cs
+
+
+ TextTemplatingFileGenerator
+ ThrowHelper.Collection.g.cs
+
+
+ TextTemplatingFileGenerator
+ TypeInfo.g.cs
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Guard.Comparable.Numeric.tt
+
+
+ True
+ True
+ Guard.Collection.tt
+
+
+ True
+ True
+ ThrowHelper.Collection.tt
+
+
+ True
+ True
+ TypeInfo.ttinclude
+
+
+
+
diff --git a/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs b/Microsoft.Toolkit.Diagnostics/ThrowHelper.Generic.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs
rename to Microsoft.Toolkit.Diagnostics/ThrowHelper.Generic.cs
diff --git a/Microsoft.Toolkit/Diagnostics/ThrowHelper.cs b/Microsoft.Toolkit.Diagnostics/ThrowHelper.cs
similarity index 100%
rename from Microsoft.Toolkit/Diagnostics/ThrowHelper.cs
rename to Microsoft.Toolkit.Diagnostics/ThrowHelper.cs
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs
index 5e15a7de772..1dcbee0c547 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs
@@ -6,7 +6,6 @@
using System;
using System.Numerics;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
@@ -605,7 +604,7 @@ public AnimationBuilder Transform(
{
if (!Matrix4x4.Decompose(to, out Vector3 toScale, out Quaternion toRotation, out Vector3 toTranslation))
{
- ThrowHelper.ThrowArgumentException("The destination matrix could not be decomposed");
+ ThrowThrowArgumentExceptionForToDecompose();
}
Vector3? fromScale = null;
@@ -616,7 +615,7 @@ public AnimationBuilder Transform(
{
if (!Matrix4x4.Decompose(from.GetValueOrDefault(), out Vector3 scale3, out Quaternion rotation4, out Vector3 translation3))
{
- ThrowHelper.ThrowArgumentException("The initial matrix could not be decomposed");
+ ThrowThrowArgumentExceptionForFromDecompose();
}
fromScale = scale3;
@@ -629,6 +628,9 @@ public AnimationBuilder Transform(
Translation(toTranslation, fromTranslation, delay, duration, easingType, easingMode);
return this;
+
+ static void ThrowThrowArgumentExceptionForToDecompose() => throw new ArgumentException("The destination matrix could not be decomposed");
+ static void ThrowThrowArgumentExceptionForFromDecompose() => throw new ArgumentException("The initial matrix could not be decomposed");
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs
index 455603b2aea..890420badd8 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs
@@ -6,7 +6,6 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
-using Microsoft.Toolkit.Diagnostics;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Composition;
@@ -161,7 +160,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo
easingFunction);
}
- return ThrowHelper.ThrowInvalidOperationException("Invalid animation type");
+ throw new InvalidOperationException("Invalid animation type");
}
///
@@ -216,7 +215,7 @@ public Timeline GetAnimation(DependencyObject targetHint)
easingFunction);
}
- return ThrowHelper.ThrowInvalidOperationException("Invalid animation type");
+ throw new InvalidOperationException("Invalid animation type");
}
///
@@ -229,9 +228,33 @@ public Timeline GetAnimation(DependencyObject targetHint)
private TValue GetToAs()
where TValue : unmanaged
{
- T to = To;
-
- return Unsafe.As(ref to);
+ // We employ this (T2)(object)t1 pattern multiple times in this library to alter generics.
+ // This is an equivalent but safer alternative to using Unsafe.As(ref TFrom).
+ // For instance, this method will result in the following IL being emitted:
+ // =============================
+ // IL_0000: ldarg.0
+ // IL_0001: call instance !0 class AnimationFactory`1::get_To()
+ // IL_0006: box !T
+ // IL_000b: unbox.any !!TValue
+ // IL_0010: ret
+ // =============================
+ // The key point is that the JIT (and AOT compilers such as .NET Native) can recognize this
+ // pattern and optimize the boxing away in case the types match. This is the case whenever
+ // the generic arguments are value types, which due to generic types in .NET being reified
+ // results in a completely different generic instantiation of the same method, making the
+ // type arguments effectively constant values known at compile time, ie. at JIT time.
+ // As a result of this, the boxing is completely avoided and the value is returned directly.
+ // Leveraging this pattern lets us keep the same optimal codegen while avoiding the extra
+ // NuGet package dependency on UWP, and the more dangerous path using the Unsafe APIs.
+ // As an example, assuming T is float, the JIT will produce the following codegen on x64:
+ // =============================
+ // L0000: vzeroupper
+ // L0003: vmovss xmm0, [rcx+8]
+ // L0008: ret
+ // =============================
+ // We can see how the property value is loaded directly from the underlying field and
+ // then returned to the caller: no boxing or unwanted overhead is introduced at all.
+ return (TValue)(object)To;
}
///
@@ -251,7 +274,7 @@ private TValue GetToAs()
T from = From.GetValueOrDefault();
- return Unsafe.As(ref from);
+ return (TValue)(object)from;
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs
index df9bc575253..b22634fdb0e 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs
@@ -9,7 +9,7 @@
namespace Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers
{
///
- /// A small generic builder type that allows to create instances.
+ /// A small generic builder type that allows to create instances.
///
/// The type of items to create a sequence of.
internal struct ListBuilder
@@ -56,14 +56,14 @@ public void Append(T item)
}
///
- /// Gets a instance with the current items.
+ /// Gets a instance with the current items.
///
- /// A instance with the current items.
+ /// A instance with the current items.
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ReadOnlySpan AsSpan()
+ public ArraySegment GetArraySegment()
{
- return this.array.AsSpan(0, this.index);
+ return new(this.array, 0, this.index);
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs
index e5dc6fb44e8..718ee6781ae 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs
@@ -4,7 +4,6 @@
using System;
using System.Numerics;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI;
using Windows.UI.Composition;
using Windows.UI.Xaml.Media.Animation;
@@ -33,7 +32,7 @@ public static CompositionAnimation GetAnimation(
TimeSpan? delay,
TimeSpan duration,
RepeatOption repeat,
- ReadOnlySpan keyFrames)
+ ArraySegment keyFrames)
where TKeyFrame : struct, IKeyFrameInfo
{
KeyFrameAnimation animation;
@@ -42,7 +41,7 @@ public static CompositionAnimation GetAnimation(
{
BooleanKeyFrameAnimation boolAnimation = target.Compositor.CreateBooleanKeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(boolAnimation, duration))
{
@@ -58,7 +57,7 @@ public static CompositionAnimation GetAnimation(
{
ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(scalarAnimation, duration))
{
@@ -83,7 +82,7 @@ public static CompositionAnimation GetAnimation(
{
ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(scalarAnimation, duration))
{
@@ -108,7 +107,7 @@ public static CompositionAnimation GetAnimation(
{
Vector2KeyFrameAnimation vector2Animation = target.Compositor.CreateVector2KeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(vector2Animation, duration))
{
@@ -133,7 +132,7 @@ public static CompositionAnimation GetAnimation(
{
Vector3KeyFrameAnimation vector3Animation = target.Compositor.CreateVector3KeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(vector3Animation, duration))
{
@@ -158,7 +157,7 @@ public static CompositionAnimation GetAnimation(
{
Vector4KeyFrameAnimation vector4Animation = target.Compositor.CreateVector4KeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(vector4Animation, duration))
{
@@ -183,7 +182,7 @@ public static CompositionAnimation GetAnimation(
{
ColorKeyFrameAnimation colorAnimation = target.Compositor.CreateColorKeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(colorAnimation, duration))
{
@@ -208,7 +207,7 @@ public static CompositionAnimation GetAnimation(
{
QuaternionKeyFrameAnimation quaternionAnimation = target.Compositor.CreateQuaternionKeyFrameAnimation();
- foreach (ref readonly var keyFrame in keyFrames)
+ foreach (var keyFrame in keyFrames)
{
if (keyFrame.TryInsertExpressionKeyFrame(quaternionAnimation, duration))
{
@@ -231,7 +230,7 @@ public static CompositionAnimation GetAnimation(
}
else
{
- return ThrowHelper.ThrowInvalidOperationException("Invalid animation type");
+ throw new InvalidOperationException("Invalid animation type");
}
animation.Duration = duration;
@@ -284,7 +283,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo
this.delay,
this.duration,
this.repeat,
- this.keyFrames.AsSpan());
+ this.keyFrames.GetArraySegment());
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs
index 23665b9544b..a5727d42d0b 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs
@@ -45,7 +45,7 @@ public Timeline GetAnimation(DependencyObject targetHint)
this.delay,
this.duration,
this.repeat,
- this.keyFrames.AsSpan());
+ this.keyFrames.GetArraySegment());
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs
index ef707c415d6..4542c36551b 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs
@@ -150,7 +150,7 @@ public KeyFrameInfo(
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TValue GetValueAs()
{
- return Unsafe.As(ref Unsafe.AsRef(in this.value));
+ return (TValue)(object)this.value;
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs
index 066e7ad6c1a..772aa7f90a7 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs
@@ -47,8 +47,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo
// We can retrieve the total duration from the last timed keyframe, and then set
// this as the target duration and use it to normalize the keyframe progresses.
- ReadOnlySpan keyFrames = this.keyFrames.AsSpan();
- TimeSpan duration = keyFrames[keyFrames.Length - 1].GetTimedProgress(default);
+ ArraySegment keyFrames = this.keyFrames.GetArraySegment();
+ TimeSpan duration = keyFrames[keyFrames.Count - 1].GetTimedProgress(default);
return NormalizedKeyFrameAnimationBuilder.GetAnimation(
targetHint,
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs
index ee6042a7a07..1c73463697b 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
-using Microsoft.Toolkit.Diagnostics;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
@@ -32,7 +31,7 @@ public static Timeline GetAnimation(
TimeSpan? delay,
TimeSpan duration,
RepeatOption repeat,
- ReadOnlySpan keyFrames)
+ ArraySegment keyFrames)
where TKeyFrame : struct, IKeyFrameInfo
{
Timeline animation;
@@ -118,7 +117,9 @@ public static Timeline GetAnimation(
}
else
{
- return ThrowHelper.ThrowInvalidOperationException("Invalid animation type");
+ static Timeline ThrowInvalidOperationException() => throw new InvalidOperationException("Invalid animation type");
+
+ return ThrowInvalidOperationException();
}
animation.BeginTime = delay;
@@ -163,7 +164,7 @@ public Timeline GetAnimation(DependencyObject targetHint)
this.delay,
default,
this.repeat,
- this.keyFrames.AsSpan());
+ this.keyFrames.GetArraySegment());
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs
index 6c0368d6f55..8a55f7d296f 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs
@@ -143,7 +143,7 @@ public KeyFrameInfo(
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TValue GetValueAs()
{
- return Unsafe.As(ref Unsafe.AsRef(in this.value));
+ return (TValue)(object)this.value;
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs
index e40c9033170..ae4081f56f1 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs
@@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Numerics;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
@@ -111,7 +110,7 @@ public static class Composition
Axis.X => "AnchorPoint.X",
Axis.Y => "AnchorPoint.Y",
Axis.Z => "AnchorPoint.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -132,7 +131,7 @@ public static class Composition
Axis.X => "Translation.X",
Axis.Y => "Translation.Y",
Axis.Z => "Translation.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -153,7 +152,7 @@ public static class Composition
Axis.X => "Offset.X",
Axis.Y => "Offset.Y",
Axis.Z => "Offset.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -174,7 +173,7 @@ public static class Composition
Axis.X => "Scale.X",
Axis.Y => "Scale.Y",
Axis.Z => "Scale.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -195,7 +194,7 @@ public static class Composition
Axis.X => "CenterPoint.X",
Axis.Y => "CenterPoint.Y",
Axis.Z => "CenterPoint.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -217,7 +216,7 @@ public static class Composition
Side.Bottom => nameof(InsetClip.BottomInset),
Side.Right => nameof(InsetClip.RightInset),
Side.Left => nameof(InsetClip.LeftInset),
- _ => ThrowHelper.ThrowArgumentException("Invalid clip side")
+ _ => ThrowArgumentException("Invalid clip side")
};
///
@@ -238,7 +237,7 @@ public static class Composition
Axis.X => "Size.X",
Axis.Y => "Size.Y",
Axis.Z => "Size.Z",
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
}
@@ -257,7 +256,7 @@ public static class Xaml
{
Axis.X => nameof(CompositeTransform.TranslateX),
Axis.Y => nameof(CompositeTransform.TranslateY),
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -270,7 +269,7 @@ public static class Xaml
{
Axis.X => nameof(CompositeTransform.ScaleX),
Axis.Y => nameof(CompositeTransform.ScaleY),
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -283,7 +282,7 @@ public static class Xaml
{
Axis.X => nameof(CompositeTransform.CenterX),
Axis.Y => nameof(CompositeTransform.CenterY),
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
///
@@ -296,9 +295,17 @@ public static class Xaml
{
Axis.X => nameof(FrameworkElement.Width),
Axis.Y => nameof(FrameworkElement.Height),
- _ => ThrowHelper.ThrowArgumentException("Invalid axis")
+ _ => ThrowArgumentException("Invalid axis")
};
}
+
+ ///
+ /// Throws a new with a given message.
+ ///
+ private static T ThrowArgumentException(string message)
+ {
+ throw new ArgumentException(message);
+ }
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs
index 039f807f4f5..325a0cb6814 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs
@@ -4,8 +4,8 @@
#nullable enable
+using System;
using System.Diagnostics.Contracts;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Xaml.Media.Animation;
using static Microsoft.Toolkit.Uwp.UI.Animations.AnimationExtensions;
@@ -46,8 +46,10 @@ public static class EasingTypeExtensions
EasingType.Quintic => new QuinticEase { EasingMode = easingMode },
EasingType.Sine => new SineEase { EasingMode = easingMode },
- _ => ThrowHelper.ThrowArgumentException("Invalid easing type")
+ _ => ThrowArgumentException()
};
+
+ static EasingFunctionBase ThrowArgumentException() => throw new ArgumentException("Invalid easing type");
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ScrollViewerExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ScrollViewerExtensions.cs
index a11b6b27b11..09bf2781bf4 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ScrollViewerExtensions.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ScrollViewerExtensions.cs
@@ -2,8 +2,8 @@
// 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.Numerics;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -66,11 +66,13 @@ public static ExpressionAnimation StartExpressionAnimation(
visual.StartAnimation($"{nameof(Visual.Offset)}.{targetAxis}", animation);
break;
default:
- ThrowHelper.ThrowArgumentException("Invalid target property");
+ ThrowArgumentException();
break;
}
return animation;
+
+ static ExpressionAnimation ThrowArgumentException() => throw new ArgumentException("Invalid target property");
}
}
}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs
index 62515f7a833..58ee14c03fd 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs
@@ -4,7 +4,6 @@
using System;
using System.Diagnostics.Contracts;
-using Microsoft.Toolkit.Diagnostics;
using Windows.Foundation.Metadata;
using Windows.UI.Composition;
using Windows.UI.Xaml.Media.Animation;
@@ -52,7 +51,10 @@ private RepeatOption(int value)
[Pure]
public static RepeatOption Count(int count)
{
- Guard.IsGreaterThanOrEqualTo(count, 0, nameof(count));
+ if (count < 0)
+ {
+ ThrowArgumentOutOfRangeForCount();
+ }
return new(count);
}
@@ -76,7 +78,7 @@ public static RepeatOption Parse(string text)
return Forever;
}
- return ThrowHelper.ThrowArgumentException("Invalid input text");
+ return ThrowArgumentExceptionForText();
}
///
@@ -109,5 +111,21 @@ public RepeatBehavior ToRepeatBehavior()
return (AnimationIterationBehavior.Count, this.value);
}
+
+ ///
+ /// Throws a new when the constructor is invoked with an incorrect parameter.
+ ///
+ private static void ThrowArgumentOutOfRangeForCount()
+ {
+ throw new ArgumentOutOfRangeException("The parameter \"count\" must be greater than or equal to 0.");
+ }
+
+ ///
+ /// Throws a new when the constructor is invoked with an incorrect parameter.
+ ///
+ private static RepeatOption ThrowArgumentExceptionForText()
+ {
+ throw new ArgumentException("The input text is not valid to parse a new RepeatOption instance. It must be either a natural number or \"Forever\".");
+ }
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs
index 3abc6a08e84..c74a4c5c533 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs
@@ -2,9 +2,9 @@
// 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.Threading;
using System.Threading.Tasks;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Uwp.UI.Animations
@@ -53,7 +53,10 @@ public UIElement TargetObject
///
public override async Task InvokeAsync(UIElement element, CancellationToken token)
{
- Guard.IsNotNull(Animation, nameof(Animation));
+ if (Animation is null)
+ {
+ ThrowArgumentNullException();
+ }
await base.InvokeAsync(element, token);
@@ -72,6 +75,8 @@ public override async Task InvokeAsync(UIElement element, CancellationToken toke
{
await Animation.StartAsync(token);
}
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation));
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs
index 58a174ea7f2..6fb686ccb82 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs
@@ -2,9 +2,9 @@
// 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.Threading;
using System.Threading.Tasks;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Uwp.UI.Animations
@@ -53,7 +53,10 @@ public UIElement TargetObject
///
public override async Task InvokeAsync(UIElement element, CancellationToken token)
{
- Guard.IsNotNull(Animation, nameof(Animation));
+ if (Animation is null)
+ {
+ ThrowArgumentNullException();
+ }
await base.InvokeAsync(element, token);
@@ -69,6 +72,8 @@ public override async Task InvokeAsync(UIElement element, CancellationToken toke
{
Animation.Stop();
}
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation));
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs
index 22441c8409f..c2cefeb6a6e 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs
@@ -9,7 +9,6 @@
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Uwp.UI.Animations
@@ -218,10 +217,12 @@ private UIElement GetParent()
if (ParentReference?.TryGetTarget(out parent) != true)
{
- ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance.");
+ ThrowInvalidOperationException();
}
return parent!;
+
+ static void ThrowInvalidOperationException() => throw new InvalidOperationException("The current AnimationSet object isn't bound to a parent UIElement instance.");
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs
index 2cbf0da37c2..eda7836e7f4 100644
--- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs
@@ -6,7 +6,6 @@
using System;
using System.Diagnostics.Contracts;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;
@@ -85,10 +84,12 @@ private UIElement GetParent()
if (ParentReference?.TryGetTarget(out parent) != true)
{
- ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance.");
+ ThrowInvalidOperationException();
}
return parent!;
+
+ static void ThrowInvalidOperationException() => throw new InvalidOperationException("The current ImplicitAnimationSet object isn't bound to a parent UIElement instance.");
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs
index aa75926d7fc..72f65dec6cf 100644
--- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs
@@ -2,7 +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 Microsoft.Toolkit.Diagnostics;
+using System;
using Microsoft.Toolkit.Uwp.UI.Animations;
using Microsoft.Xaml.Interactivity;
using Windows.UI.Xaml;
@@ -53,7 +53,10 @@ public UIElement TargetObject
///
public object Execute(object sender, object parameter)
{
- Guard.IsNotNull(Animation, nameof(Animation));
+ if (Animation is null)
+ {
+ ThrowArgumentNullException();
+ }
if (TargetObject is not null)
{
@@ -65,6 +68,8 @@ public object Execute(object sender, object parameter)
}
return null!;
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation));
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StopAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StopAnimationAction.cs
index 52f889b6bdd..c8f2a197950 100644
--- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StopAnimationAction.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StopAnimationAction.cs
@@ -2,7 +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 Microsoft.Toolkit.Diagnostics;
+using System;
using Microsoft.Toolkit.Uwp.UI.Animations;
using Microsoft.Xaml.Interactivity;
using Windows.UI.Xaml;
@@ -53,7 +53,10 @@ public UIElement TargetObject
///
public object Execute(object sender, object parameter)
{
- Guard.IsNotNull(Animation, nameof(Animation));
+ if (Animation is null)
+ {
+ ThrowArgumentNullException();
+ }
if (TargetObject is not null)
{
@@ -65,6 +68,8 @@ public object Execute(object sender, object parameter)
}
return null!;
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation));
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ColorPicker/ColorPicker.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ColorPicker/ColorPicker.cs
index cb7398d9791..8dbe534bf94 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/ColorPicker/ColorPicker.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/ColorPicker/ColorPicker.cs
@@ -3,14 +3,11 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
-using Microsoft.Toolkit.Diagnostics;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters;
-using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -233,10 +230,12 @@ private T GetTemplateChild(string childName, bool isRequired = false)
T child = this.GetTemplateChild(childName) as T;
if ((child == null) && isRequired)
{
- ThrowHelper.ThrowArgumentNullException(childName);
+ ThrowArgumentNullException();
}
return child;
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(childName));
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/InterspersedObservableCollection.cs b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/InterspersedObservableCollection.cs
index 74fc28fd5d1..c0c84fef849 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/InterspersedObservableCollection.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/InterspersedObservableCollection.cs
@@ -5,11 +5,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Collections.Immutable;
using System.Collections.Specialized;
-using System.ComponentModel;
using System.Linq;
-using Microsoft.Toolkit.Diagnostics;
using Microsoft.Toolkit.Uwp.Helpers;
namespace Microsoft.Toolkit.Uwp.UI.Controls
@@ -54,9 +51,12 @@ public object this[int index]
public InterspersedObservableCollection(object itemsSource)
{
- Guard.IsAssignableToType(itemsSource, nameof(itemsSource));
+ if (!(itemsSource is IList list))
+ {
+ ThrowArgumentException();
+ }
- ItemsSource = itemsSource as IList;
+ ItemsSource = list;
if (ItemsSource is INotifyCollectionChanged notifier)
{
@@ -67,6 +67,8 @@ public InterspersedObservableCollection(object itemsSource)
};
notifier.CollectionChanged += weakPropertyChangedListener.OnEvent;
}
+
+ static void ThrowArgumentException() => throw new ArgumentNullException("The input items source must be assignable to the System.Collections.IList type.");
}
private void ItemsSource_CollectionChanged(object source, NotifyCollectionChangedEventArgs eventArgs)
@@ -192,12 +194,20 @@ private void ReadjustKeys()
/// Inner ItemsSource Index.
private int ToInnerIndex(int outerIndex)
{
-#if DEBUG
- Guard.IsInRange(outerIndex, 0, Count, nameof(outerIndex));
- Guard.IsFalse(_interspersedObjects.ContainsKey(outerIndex), nameof(outerIndex)); // We can't map a inserted key to the original collection!
-#endif
+ if ((uint)outerIndex >= Count)
+ {
+ ThrowArgumentOutOfRangeException();
+ }
+
+ if (_interspersedObjects.ContainsKey(outerIndex))
+ {
+ ThrowArgumentException();
+ }
return outerIndex - _interspersedObjects.Keys.Count(key => key.Value <= outerIndex);
+
+ static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException(nameof(outerIndex));
+ static void ThrowArgumentException() => throw new ArgumentException("The outer index can't be inserted as a key to the original collection.");
}
///
@@ -207,9 +217,10 @@ private int ToInnerIndex(int outerIndex)
/// Index into the entire collection.
private int ToOuterIndex(int innerIndex)
{
-#if DEBUG
- Guard.IsInRange(innerIndex, 0, ItemsSource.Count, nameof(innerIndex));
-#endif
+ if ((uint)innerIndex >= ItemsSource.Count)
+ {
+ ThrowArgumentOutOfRangeException();
+ }
var keys = _interspersedObjects.OrderBy(v => v.Key);
@@ -226,6 +237,8 @@ private int ToOuterIndex(int innerIndex)
}
return innerIndex;
+
+ static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException(nameof(innerIndex));
}
///
@@ -235,9 +248,10 @@ private int ToOuterIndex(int innerIndex)
/// Projected index in the entire collection.
private int ToOuterIndexAfterRemoval(int innerIndexToProject)
{
-#if DEBUG
- Guard.IsInRange(innerIndexToProject, 0, ItemsSource.Count + 1, nameof(innerIndexToProject));
-#endif
+ if ((uint)innerIndexToProject >= ItemsSource.Count + 1)
+ {
+ ThrowArgumentOutOfRangeException();
+ }
//// TODO: Deal with bounds (0 / Count)? Or is it the same?
@@ -256,6 +270,8 @@ private int ToOuterIndexAfterRemoval(int innerIndexToProject)
}
return innerIndexToProject;
+
+ static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException(nameof(innerIndexToProject));
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/TakenSpotsReferenceHolder.cs b/Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/TakenSpotsReferenceHolder.cs
index 9474082e25e..0092a1275cb 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/TakenSpotsReferenceHolder.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/TakenSpotsReferenceHolder.cs
@@ -4,7 +4,6 @@
using System.Collections;
using System.Drawing;
-using Microsoft.Toolkit.Diagnostics;
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
@@ -28,9 +27,6 @@ internal sealed class TakenSpotsReferenceHolder
/// The number of columns to track.
public TakenSpotsReferenceHolder(int rows, int columns)
{
- Guard.IsGreaterThanOrEqualTo(rows, 0, nameof(rows));
- Guard.IsGreaterThanOrEqualTo(columns, 0, nameof(columns));
-
Height = rows;
Width = columns;
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.Data.cs b/Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.Data.cs
index c3112d9bd96..cf8ac47ed52 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.Data.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.Data.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
-using Microsoft.Toolkit.Diagnostics;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
@@ -63,8 +62,10 @@ private struct UvRect
{
Orientation.Vertical => new Rect(Position.V, Position.U, Size.V, Size.U),
Orientation.Horizontal => new Rect(Position.U, Position.V, Size.U, Size.V),
- _ => ThrowHelper.ThrowNotSupportedException("unsupported orientation"),
+ _ => ThrowArgumentException()
};
+
+ private static Rect ThrowArgumentException() => throw new ArgumentException("The input orientation is not valid.");
}
private struct Row
diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs
index b2f2f697824..faaa78dd171 100644
--- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
-using Microsoft.Toolkit.Diagnostics;
using Microsoft.Toolkit.Uwp.UI.Media;
using Windows.UI.Composition;
using Windows.UI.Xaml;
@@ -50,14 +49,21 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS
{
if (Target is not TEffect target)
{
- return ThrowHelper.ThrowArgumentNullException("The target effect is null, make sure to set the Target property");
+ static AnimationBuilder ThrowArgumentNullException() => throw new ArgumentNullException("The target effect is null, make sure to set the Target property");
+
+ return ThrowArgumentNullException();
}
if (ExplicitTarget is not string explicitTarget)
{
- return ThrowHelper.ThrowArgumentNullException(
- "The target effect cannot be animated at this time. If you're targeting one of the " +
- "built-in effects, make sure that the PipelineEffect.IsAnimatable property is set to true.");
+ static AnimationBuilder ThrowArgumentNullException()
+ {
+ throw new ArgumentNullException(
+ "The target effect cannot be animated at this time. If you're targeting one of the " +
+ "built-in effects, make sure that the PipelineEffect.IsAnimatable property is set to true.");
+ }
+
+ return ThrowArgumentNullException();
}
NormalizedKeyFrameAnimationBuilder.Composition keyFrameBuilder = new(
@@ -70,7 +76,7 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS
CompositionAnimation animation = keyFrameBuilder.GetAnimation(target.Brush!, out _);
- return builder.ExternalAnimation(target.Brush, animation);
+ return builder.ExternalAnimation(target.Brush!, animation);
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs
index 85b3770dab1..1b2b323b15d 100644
--- a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs
@@ -6,7 +6,6 @@
using System.Globalization;
using System.Linq;
using System.Numerics;
-using System.Runtime.CompilerServices;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;
@@ -165,11 +164,11 @@ public static Vector4 ToVector4(this string str)
///
/// A string in the format of "float, float, float, float"
///
- public static Quaternion ToQuaternion(this string str)
+ public static unsafe Quaternion ToQuaternion(this string str)
{
Vector4 vector = str.ToVector4();
- return Unsafe.As(ref vector);
+ return *(Quaternion*)&vector;
}
///
diff --git a/Microsoft.Toolkit.Uwp.UI/Helpers/CompositionTargetHelper.cs b/Microsoft.Toolkit.Uwp.UI/Helpers/CompositionTargetHelper.cs
index 08a6741cf50..24a7bc18801 100644
--- a/Microsoft.Toolkit.Uwp.UI/Helpers/CompositionTargetHelper.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Helpers/CompositionTargetHelper.cs
@@ -4,7 +4,6 @@
using System;
using System.Threading.Tasks;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI.Xaml.Media;
namespace Microsoft.Toolkit.Uwp.UI.Helpers
@@ -22,7 +21,10 @@ public static class CompositionTargetHelper
/// Awaitable Task
public static Task ExecuteAfterCompositionRenderingAsync(Action action)
{
- Guard.IsNotNull(action, nameof(action));
+ if (action is null)
+ {
+ ThrowArgumentNullException();
+ }
var taskCompletionSource = new TaskCompletionSource();
@@ -45,6 +47,8 @@ void Callback(object sender, object args)
}
return taskCompletionSource.Task;
+
+ static void ThrowArgumentNullException() => throw new ArgumentNullException("The parameter \"action\" must not be null.");
}
}
}
diff --git a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
index edb24421aca..e7358bf1939 100644
--- a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
+++ b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
@@ -40,8 +40,8 @@
- ThemeListener: Class which listens for changes to Application Theme or High Contrast Modes and Signals an Event when they occur.
UWP Toolkit Windows UI Converters XAML extensions helpers
-
true
+ true
diff --git a/Microsoft.Toolkit.Uwp/Helpers/ColorHelper.cs b/Microsoft.Toolkit.Uwp/Helpers/ColorHelper.cs
index f3f82615034..ff6cb38c314 100644
--- a/Microsoft.Toolkit.Uwp/Helpers/ColorHelper.cs
+++ b/Microsoft.Toolkit.Uwp/Helpers/ColorHelper.cs
@@ -5,7 +5,6 @@
using System;
using System.Globalization;
using System.Reflection;
-using Microsoft.Toolkit.Diagnostics;
using Windows.UI;
using Color = Windows.UI.Color;
@@ -24,7 +23,10 @@ public static class ColorHelper
/// The created .
public static Color ToColor(this string colorString)
{
- Guard.IsNotNullOrEmpty(colorString, nameof(colorString));
+ if (string.IsNullOrEmpty(colorString))
+ {
+ ThrowArgumentException();
+ }
if (colorString[0] == '#')
{
@@ -79,7 +81,7 @@ public static Color ToColor(this string colorString)
return Color.FromArgb(255, r, g, b);
}
- default: return ThrowHelper.ThrowFormatException("The string passed in the colorString argument is not a recognized Color format.");
+ default: return ThrowFormatException();
}
}
@@ -106,7 +108,7 @@ public static Color ToColor(this string colorString)
return Color.FromArgb(255, (byte)(scR * 255), (byte)(scG * 255), (byte)(scB * 255));
}
- return ThrowHelper.ThrowFormatException("The string passed in the colorString argument is not a recognized Color format (sc#[scA,]scR,scG,scB).");
+ return ThrowFormatException();
}
var prop = typeof(Colors).GetTypeInfo().GetDeclaredProperty(colorString);
@@ -116,7 +118,10 @@ public static Color ToColor(this string colorString)
return (Color)prop.GetValue(null);
}
- return ThrowHelper.ThrowFormatException("The string passed in the colorString argument is not a recognized Color.");
+ return ThrowFormatException();
+
+ static void ThrowArgumentException() => throw new ArgumentException("The parameter \"colorString\" must not be null or empty.");
+ static Color ThrowFormatException() => throw new FormatException("The parameter \"colorString\" is not a recognized Color format.");
}
///
diff --git a/Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/SystemSerializer.cs b/Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/SystemSerializer.cs
index 61f247d3eed..07da5edd20f 100644
--- a/Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/SystemSerializer.cs
+++ b/Microsoft.Toolkit.Uwp/Helpers/ObjectStorage/SystemSerializer.cs
@@ -4,7 +4,6 @@
using System;
using System.Reflection;
-using Microsoft.Toolkit.Diagnostics;
using Windows.Storage;
namespace Microsoft.Toolkit.Uwp.Helpers
@@ -31,7 +30,9 @@ public T Deserialize(object value)
return (T)Convert.ChangeType(value, type);
}
- return ThrowHelper.ThrowNotSupportedException("This serializer can only handle primitive types and strings. Please implement your own IObjectSerializer for more complex scenarios.");
+ return ThrowNotSupportedException();
+
+ static T ThrowNotSupportedException() => throw new NotSupportedException("This serializer can only handle primitive types and strings. Please implement your own IObjectSerializer for more complex scenarios.");
}
///
diff --git a/Microsoft.Toolkit/Microsoft.Toolkit.csproj b/Microsoft.Toolkit/Microsoft.Toolkit.csproj
index b071ab13cdb..eaaa8c91009 100644
--- a/Microsoft.Toolkit/Microsoft.Toolkit.csproj
+++ b/Microsoft.Toolkit/Microsoft.Toolkit.csproj
@@ -13,85 +13,15 @@
UWP Toolkit Windows IncrementalLoadingCollection String Array extensions helpers
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- NETSTANDARD2_1_OR_GREATER
-
-
-
-
-
-
-
-
-
- NETSTANDARD2_1_OR_GREATER
-
-
-
-
-
-
- TextTemplatingFileGenerator
- Guard.Comparable.Numeric.g.cs
-
-
- TextTemplatingFileGenerator
- Guard.Collection.g.cs
-
-
- TextTemplatingFileGenerator
- ThrowHelper.Collection.g.cs
-
-
- TextTemplatingFileGenerator
- TypeInfo.g.cs
-
+
+
+
-
-
-
-
-
-
-
- True
- True
- Guard.Comparable.Numeric.tt
-
-
- True
- True
- Guard.Collection.tt
-
-
- True
- True
- ThrowHelper.Collection.tt
-
-
- True
- True
- TypeInfo.ttinclude
-
-
+
+
+ NETSTANDARD2_1_OR_GREATER
+
diff --git a/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml b/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml
new file mode 100644
index 00000000000..f1f78423b2d
--- /dev/null
+++ b/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml.cs b/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml.cs
new file mode 100644
index 00000000000..31c5af761cb
--- /dev/null
+++ b/SmokeTests/Microsoft.Toolkit.Diagnostics/MainPage.xaml.cs
@@ -0,0 +1,23 @@
+// 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 Microsoft.Toolkit.Diagnostics;
+
+namespace SmokeTest
+{
+ public sealed partial class MainPage
+ {
+ public MainPage()
+ {
+ InitializeComponent();
+ }
+
+ private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
+ {
+ Guard.IsNotNullOrEmpty(textBox.Text, nameof(textBox));
+
+ textBlock.Text = "Ok";
+ }
+ }
+}
diff --git a/SmokeTests/SmokeTests.proj b/SmokeTests/SmokeTests.proj
index d856a867110..d23ce403d2e 100644
--- a/SmokeTests/SmokeTests.proj
+++ b/SmokeTests/SmokeTests.proj
@@ -7,6 +7,7 @@
UWPBaseline;
Microsoft.Toolkit;
+ Microsoft.Toolkit.Diagnostics;
Microsoft.Toolkit.HighPerformance;
Microsoft.Toolkit.Mvvm;
Microsoft.Toolkit.Parsers;
diff --git a/UnitTests/UnitTests.NetCore/UnitTests.NetCore.csproj b/UnitTests/UnitTests.NetCore/UnitTests.NetCore.csproj
index fd6b9d7a4dc..f4f7296db23 100644
--- a/UnitTests/UnitTests.NetCore/UnitTests.NetCore.csproj
+++ b/UnitTests/UnitTests.NetCore/UnitTests.NetCore.csproj
@@ -20,6 +20,7 @@
+
diff --git a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
index c2bc7e1cc2a..0c9df38b3d9 100644
--- a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
+++ b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
@@ -232,6 +232,10 @@
+
+ {76f89522-ca28-458d-801d-947ab033a758}
+ Microsoft.Toolkit.Diagnostics
+
{d82ae6e1-e612-434e-acb2-363ee48738d3}
Microsoft.Toolkit.Mvvm
diff --git a/Windows Community Toolkit.sln b/Windows Community Toolkit.sln
index 9f57b24e708..28c7a6adf5e 100644
--- a/Windows Community Toolkit.sln
+++ b/Windows Community Toolkit.sln
@@ -137,6 +137,8 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UITests.Tests.Shared", "UIT
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Toolkit.Uwp.UI.Behaviors", "Microsoft.Toolkit.Uwp.UI.Behaviors\Microsoft.Toolkit.Uwp.UI.Behaviors.csproj", "{D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Toolkit.Diagnostics", "Microsoft.Toolkit.Diagnostics\Microsoft.Toolkit.Diagnostics.csproj", "{76F89522-CA28-458D-801D-947AB033A758}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
UITests\UITests.Tests.Shared\UITests.Tests.Shared.projitems*{05c83067-fa46-45e2-bec4-edee84ad18d0}*SharedItemsImports = 4
@@ -978,6 +980,26 @@ Global
{D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x64.Build.0 = Release|Any CPU
{D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x86.ActiveCfg = Release|Any CPU
{D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x86.Build.0 = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|ARM.Build.0 = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|x64.Build.0 = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Debug|x86.Build.0 = Debug|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|Any CPU.Build.0 = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|ARM.ActiveCfg = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|ARM.Build.0 = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|ARM64.Build.0 = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|x64.ActiveCfg = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|x64.Build.0 = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|x86.ActiveCfg = Release|Any CPU
+ {76F89522-CA28-458D-801D-947AB033A758}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE