Merge branch 'master' into jamesmcroft/3506-carousel-automation
This commit is contained in:
Коммит
951774d682
|
@ -1,5 +1,8 @@
|
|||
<!-- 🚨 Please Do Not skip any instructions and information mentioned below as they are all required and essential to evaluate and test the PR. By fulfilling all the required information you will be able to reduce the volume of questions and most likely help merge the PR faster 🚨 -->
|
||||
|
||||
<!-- 📝 It is preferred if you keep the "☑️ Allow edits by maintainers" checked in the Pull Request Template as it increases collaboration with the Toolkit maintainers by permitting commits to your PR branch (only) created from your fork. This can let us quickly make fixes for minor typos or forgotten StyleCop issues during review without needing to wait on you doing extra work. Let us help you help us! 🎉 -->
|
||||
|
||||
|
||||
## Fixes #
|
||||
<!-- Add the relevant issue number after the "#" mentioned above (for ex: Fixes #1234) which will automatically close the issue once the PR is merged. -->
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// 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.
|
||||
|
||||
#if !NET5_0
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to indicate to the compiler that the <c>.locals init</c> flag should not be set in method headers.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy of the .NET 5 attribute.</remarks>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Module |
|
||||
AttributeTargets.Class |
|
||||
AttributeTargets.Struct |
|
||||
AttributeTargets.Interface |
|
||||
AttributeTargets.Constructor |
|
||||
AttributeTargets.Method |
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Event,
|
||||
Inherited = false)]
|
||||
internal sealed class SkipLocalsInitAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,7 +7,7 @@ using System.Buffers;
|
|||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCORE_RUNTIME
|
||||
#if NETCORE_RUNTIME || NET5_0
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers.Views;
|
||||
|
@ -183,7 +183,7 @@ namespace Microsoft.Toolkit.HighPerformance.Buffers
|
|||
ThrowObjectDisposedException();
|
||||
}
|
||||
|
||||
#if NETCORE_RUNTIME
|
||||
#if NETCORE_RUNTIME || NET5_0
|
||||
ref T r0 = ref array!.DangerousGetReferenceAt(this.start);
|
||||
|
||||
// On .NET Core runtimes, we can manually create a span from the starting reference to
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Buffers;
|
|||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCORE_RUNTIME
|
||||
#if NETCORE_RUNTIME || NET5_0
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers.Views;
|
||||
|
@ -148,7 +148,7 @@ namespace Microsoft.Toolkit.HighPerformance.Buffers
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
#if NETCORE_RUNTIME
|
||||
#if NETCORE_RUNTIME || NET5_0
|
||||
ref T r0 = ref array!.DangerousGetReference();
|
||||
|
||||
return MemoryMarshal.CreateSpan(ref r0, this.length);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// 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.
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCORE_RUNTIME
|
||||
#if NETCORE_RUNTIME || NET5_0
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using Microsoft.Toolkit.HighPerformance.Enumerables;
|
||||
|
@ -30,7 +30,9 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T DangerousGetReference<T>(this T[] array)
|
||||
{
|
||||
#if NETCORE_RUNTIME
|
||||
#if NET5_0
|
||||
return ref MemoryMarshal.GetArrayDataReference(array);
|
||||
#elif NETCORE_RUNTIME
|
||||
var arrayData = Unsafe.As<RawArrayData>(array)!;
|
||||
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);
|
||||
|
||||
|
@ -54,7 +56,12 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T DangerousGetReferenceAt<T>(this T[] array, int i)
|
||||
{
|
||||
#if NETCORE_RUNTIME
|
||||
#if NET5_0
|
||||
ref T r0 = ref MemoryMarshal.GetArrayDataReference(array);
|
||||
ref T ri = ref Unsafe.Add(ref r0, (nint)(uint)i);
|
||||
|
||||
return ref ri;
|
||||
#elif NETCORE_RUNTIME
|
||||
var arrayData = Unsafe.As<RawArrayData>(array)!;
|
||||
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);
|
||||
ref T ri = ref Unsafe.Add(ref r0, (nint)(uint)i);
|
||||
|
@ -203,7 +210,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <summary>
|
||||
/// Throws an <see cref="OverflowException"/> when the "column" parameter is invalid.
|
||||
/// </summary>
|
||||
public static void ThrowOverflowException()
|
||||
private static void ThrowOverflowException()
|
||||
{
|
||||
throw new OverflowException();
|
||||
}
|
||||
|
|
|
@ -451,7 +451,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <summary>
|
||||
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "row" parameter is invalid.
|
||||
/// </summary>
|
||||
public static void ThrowArgumentOutOfRangeExceptionForRow()
|
||||
private static void ThrowArgumentOutOfRangeExceptionForRow()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("row");
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <summary>
|
||||
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "column" parameter is invalid.
|
||||
/// </summary>
|
||||
public static void ThrowArgumentOutOfRangeExceptionForColumn()
|
||||
private static void ThrowArgumentOutOfRangeExceptionForColumn()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("column");
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <summary>
|
||||
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "depth" parameter is invalid.
|
||||
/// </summary>
|
||||
public static void ThrowArgumentOutOfRangeExceptionForDepth()
|
||||
private static void ThrowArgumentOutOfRangeExceptionForDepth()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("depth");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// 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.Diagnostics.Contracts;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers;
|
||||
using Microsoft.Toolkit.HighPerformance.Streams;
|
||||
using Microsoft.Toolkit.HighPerformance.Streams.Sources;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Helpers for working with the <see cref="ArrayPoolBufferWriter{T}"/> type.
|
||||
/// </summary>
|
||||
public static class ArrayPoolBufferWriterExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a <see cref="Stream"/> that can be used to write to a target an <see cref="ArrayPoolBufferWriter{T}"/> of <see cref="byte"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="writer">The target <see cref="ArrayPoolBufferWriter{T}"/> instance.</param>
|
||||
/// <returns>A <see cref="Stream"/> wrapping <paramref name="writer"/> and writing data to its underlying buffer.</returns>
|
||||
/// <remarks>The returned <see cref="Stream"/> can only be written to and does not support seeking.</remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Stream AsStream(this ArrayPoolBufferWriter<byte> writer)
|
||||
{
|
||||
return new IBufferWriterStream<ArrayBufferWriterOwner>(new ArrayBufferWriterOwner(writer));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,9 +21,9 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <remarks>This method does not contain branching instructions.</remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ToByte(this bool flag)
|
||||
public static unsafe byte ToByte(this bool flag)
|
||||
{
|
||||
return Unsafe.As<bool, byte>(ref flag);
|
||||
return *(byte*)&flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -35,9 +35,9 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Obsolete("Use ToByte instead.")]
|
||||
public static int ToInt(this bool flag)
|
||||
public static unsafe int ToInt(this bool flag)
|
||||
{
|
||||
return Unsafe.As<bool, byte>(ref flag);
|
||||
return *(byte*)&flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -56,9 +56,9 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToBitwiseMask32(this bool flag)
|
||||
public static unsafe int ToBitwiseMask32(this bool flag)
|
||||
{
|
||||
byte rangeFlag = Unsafe.As<bool, byte>(ref flag);
|
||||
byte rangeFlag = *(byte*)&flag;
|
||||
int
|
||||
negativeFlag = rangeFlag - 1,
|
||||
mask = ~negativeFlag;
|
||||
|
@ -75,9 +75,9 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <remarks>This method does not contain branching instructions. See additional note in <see cref="ToBitwiseMask32"/>.</remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ToBitwiseMask64(this bool flag)
|
||||
public static unsafe long ToBitwiseMask64(this bool flag)
|
||||
{
|
||||
byte rangeFlag = Unsafe.As<bool, byte>(ref flag);
|
||||
byte rangeFlag = *(byte*)&flag;
|
||||
long
|
||||
negativeFlag = (long)rangeFlag - 1,
|
||||
mask = ~negativeFlag;
|
||||
|
|
|
@ -4,8 +4,13 @@
|
|||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers;
|
||||
using Microsoft.Toolkit.HighPerformance.Streams;
|
||||
using Microsoft.Toolkit.HighPerformance.Streams.Sources;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Extensions
|
||||
{
|
||||
|
@ -14,6 +19,28 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// </summary>
|
||||
public static class IBufferWriterExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a <see cref="Stream"/> that can be used to write to a target an <see cref="IBufferWriter{T}"/> of <see cref="byte"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="writer">The target <see cref="IBufferWriter{T}"/> instance.</param>
|
||||
/// <returns>A <see cref="Stream"/> wrapping <paramref name="writer"/> and writing data to its underlying buffer.</returns>
|
||||
/// <remarks>The returned <see cref="Stream"/> can only be written to and does not support seeking.</remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Stream AsStream(this IBufferWriter<byte> writer)
|
||||
{
|
||||
if (writer.GetType() == typeof(ArrayPoolBufferWriter<byte>))
|
||||
{
|
||||
// If the input writer is of type ArrayPoolBufferWriter<byte>, we can use the type
|
||||
// specific buffer writer owner to let the JIT elide callvirts when accessing it.
|
||||
var internalWriter = Unsafe.As<ArrayPoolBufferWriter<byte>>(writer)!;
|
||||
|
||||
return new IBufferWriterStream<ArrayBufferWriterOwner>(new ArrayBufferWriterOwner(internalWriter));
|
||||
}
|
||||
|
||||
return new IBufferWriterStream<IBufferWriterOwner>(new IBufferWriterOwner(writer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of a specified type into a target <see cref="IBufferWriter{T}"/> instance.
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// 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.
|
||||
|
||||
#if NET5_0
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Helpers for working with the <see cref="List{T}"/> type.
|
||||
/// </summary>
|
||||
public static class ListExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Span{T}"/> over an input <see cref="List{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of elements in the input <see cref="List{T}"/> instance.</typeparam>
|
||||
/// <param name="list">The input <see cref="List{T}"/> instance.</param>
|
||||
/// <returns>A <see cref="Span{T}"/> instance with the values of <paramref name="list"/>.</returns>
|
||||
/// <remarks>
|
||||
/// Note that the returned <see cref="Span{T}"/> is only guaranteed to be valid as long as the items within
|
||||
/// <paramref name="list"/> are not modified. Doing so might cause the <see cref="List{T}"/> to swap its
|
||||
/// internal buffer, causing the returned <see cref="Span{T}"/> to become out of date. That means that in this
|
||||
/// scenario, the <see cref="Span{T}"/> would end up wrapping an array no longer in use. Always make sure to use
|
||||
/// the returned <see cref="Span{T}"/> while the target <see cref="List{T}"/> is not modified.
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Span<T> AsSpan<T>(this List<T>? list)
|
||||
{
|
||||
return CollectionsMarshal.AsSpan(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -138,7 +138,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref readonly T DangerousGetLookupReferenceAt<T>(this ReadOnlySpan<T> span, int i)
|
||||
public static unsafe ref readonly T DangerousGetLookupReferenceAt<T>(this ReadOnlySpan<T> span, int i)
|
||||
{
|
||||
// Check whether the input is in range by first casting both
|
||||
// operands to uint and then comparing them, as this allows
|
||||
|
@ -156,7 +156,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
// bounds unless the input span was just empty, which for a
|
||||
// lookup table can just be assumed to always be false.
|
||||
bool isInRange = (uint)i < (uint)span.Length;
|
||||
byte rangeFlag = Unsafe.As<bool, byte>(ref isInRange);
|
||||
byte rangeFlag = *(byte*)&isInRange;
|
||||
uint
|
||||
negativeFlag = unchecked(rangeFlag - 1u),
|
||||
mask = ~negativeFlag,
|
||||
|
|
|
@ -167,24 +167,24 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
/// <returns>The <typeparamref name="T"/> value read from <paramref name="stream"/>.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if <paramref name="stream"/> reaches the end.</exception>
|
||||
#if SPAN_RUNTIME_SUPPORT
|
||||
// Avoid inlining as we're renting a stack buffer, which
|
||||
// cause issues if this method was called inside a loop
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static T Read<T>(this Stream stream)
|
||||
where T : unmanaged
|
||||
{
|
||||
#if SPAN_RUNTIME_SUPPORT
|
||||
Span<byte> span = stackalloc byte[Unsafe.SizeOf<T>()];
|
||||
T result = default;
|
||||
int length = Unsafe.SizeOf<T>();
|
||||
|
||||
if (stream.Read(span) != span.Length)
|
||||
unsafe
|
||||
{
|
||||
ThrowInvalidOperationExceptionForEndOfStream();
|
||||
if (stream.Read(new Span<byte>(&result, length)) != length)
|
||||
{
|
||||
ThrowInvalidOperationExceptionForEndOfStream();
|
||||
}
|
||||
}
|
||||
|
||||
ref byte r0 = ref MemoryMarshal.GetReference(span);
|
||||
|
||||
return Unsafe.ReadUnaligned<T>(ref r0);
|
||||
return result;
|
||||
#else
|
||||
int length = Unsafe.SizeOf<T>();
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(length);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if !NETCOREAPP3_1
|
||||
#if NETCOREAPP2_1 || NETSTANDARD
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using Microsoft.Toolkit.HighPerformance.Enumerables;
|
||||
|
@ -28,7 +28,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref char DangerousGetReference(this string text)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
return ref Unsafe.AsRef(text.GetPinnableReference());
|
||||
#elif NETCOREAPP2_1
|
||||
var stringData = Unsafe.As<RawStringData>(text)!;
|
||||
|
@ -50,7 +50,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref char DangerousGetReferenceAt(this string text, int i)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
ref char r0 = ref Unsafe.AsRef(text.GetPinnableReference());
|
||||
#elif NETCOREAPP2_1
|
||||
ref char r0 = ref Unsafe.As<RawStringData>(text)!.Data;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasFlag(uint value, int n)
|
||||
public static unsafe bool HasFlag(uint value, int n)
|
||||
{
|
||||
// Read the n-th bit, downcast to byte
|
||||
byte flag = (byte)((value >> n) & 1);
|
||||
|
@ -40,7 +40,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
// compared the previous computed flag against 0, the assembly
|
||||
// would have had to perform the test, set the non-zero
|
||||
// flag and then extend the (byte) result to eax.
|
||||
return Unsafe.As<byte, bool>(ref flag);
|
||||
return *(bool*)&flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -74,7 +74,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasLookupFlag(uint table, int x, int min = 0)
|
||||
public static unsafe bool HasLookupFlag(uint table, int x, int min = 0)
|
||||
{
|
||||
// First, the input value is scaled down by the given minimum.
|
||||
// This step will be skipped entirely if min is just the default of 0.
|
||||
|
@ -91,14 +91,14 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
// as a bool just like in the HasFlag method above, and then returned.
|
||||
int i = x - min;
|
||||
bool isInRange = (uint)i < 32u;
|
||||
byte byteFlag = Unsafe.As<bool, byte>(ref isInRange);
|
||||
byte byteFlag = *(byte*)&isInRange;
|
||||
int
|
||||
negativeFlag = byteFlag - 1,
|
||||
mask = ~negativeFlag,
|
||||
shift = unchecked((int)((table >> i) & 1)),
|
||||
and = shift & mask;
|
||||
byte result = unchecked((byte)and);
|
||||
bool valid = Unsafe.As<byte, bool>(ref result);
|
||||
bool valid = *(bool*)&result;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint SetFlag(uint value, int n, bool flag)
|
||||
public static unsafe uint SetFlag(uint value, int n, bool flag)
|
||||
{
|
||||
// Shift a bit left to the n-th position, negate the
|
||||
// resulting value and perform an AND with the input value.
|
||||
|
@ -210,7 +210,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
// operation. This will always guaranteed to work, thanks to the
|
||||
// initial code clearing that bit before setting it again.
|
||||
uint
|
||||
flag32 = Unsafe.As<bool, byte>(ref flag),
|
||||
flag32 = *(byte*)&flag,
|
||||
shift = flag32 << n,
|
||||
or = and | shift;
|
||||
|
||||
|
@ -235,7 +235,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ExtractRange(uint value, byte start, byte length)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
if (Bmi1.IsSupported)
|
||||
{
|
||||
return Bmi1.BitFieldExtract(value, start, length);
|
||||
|
@ -283,7 +283,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
loadMask = highBits << start,
|
||||
storeMask = (flags & highBits) << start;
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
if (Bmi1.IsSupported)
|
||||
{
|
||||
return Bmi1.AndNot(loadMask, value) | storeMask;
|
||||
|
@ -306,12 +306,12 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasFlag(ulong value, int n)
|
||||
public static unsafe bool HasFlag(ulong value, int n)
|
||||
{
|
||||
// Same logic as the uint version, see that for more info
|
||||
byte flag = (byte)((value >> n) & 1);
|
||||
|
||||
return Unsafe.As<byte, bool>(ref flag);
|
||||
return *(bool*)&flag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -328,18 +328,18 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasLookupFlag(ulong table, int x, int min = 0)
|
||||
public static unsafe bool HasLookupFlag(ulong table, int x, int min = 0)
|
||||
{
|
||||
int i = x - min;
|
||||
bool isInRange = (uint)i < 64u;
|
||||
byte byteFlag = Unsafe.As<bool, byte>(ref isInRange);
|
||||
byte byteFlag = *(byte*)&isInRange;
|
||||
int
|
||||
negativeFlag = byteFlag - 1,
|
||||
mask = ~negativeFlag,
|
||||
shift = unchecked((int)((table >> i) & 1)),
|
||||
and = shift & mask;
|
||||
byte result = unchecked((byte)and);
|
||||
bool valid = Unsafe.As<byte, bool>(ref result);
|
||||
bool valid = *(bool*)&result;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
@ -373,13 +373,13 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong SetFlag(ulong value, int n, bool flag)
|
||||
public static unsafe ulong SetFlag(ulong value, int n, bool flag)
|
||||
{
|
||||
ulong
|
||||
bit = 1ul << n,
|
||||
not = ~bit,
|
||||
and = value & not,
|
||||
flag64 = Unsafe.As<bool, byte>(ref flag),
|
||||
flag64 = *(byte*)&flag,
|
||||
shift = flag64 << n,
|
||||
or = and | shift;
|
||||
|
||||
|
@ -404,7 +404,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong ExtractRange(ulong value, byte start, byte length)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
if (Bmi1.X64.IsSupported)
|
||||
{
|
||||
return Bmi1.X64.BitFieldExtract(value, start, length);
|
||||
|
@ -452,7 +452,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers
|
|||
loadMask = highBits << start,
|
||||
storeMask = (flags & highBits) << start;
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
if (Bmi1.X64.IsSupported)
|
||||
{
|
||||
return Bmi1.X64.AndNot(loadMask, value) | storeMask;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
using static System.Numerics.BitOperations;
|
||||
#endif
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int RoundUpPowerOfTwo(int x)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
return 1 << (32 - LeadingZeroCount((uint)(x - 1)));
|
||||
#else
|
||||
x--;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// 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.
|
||||
|
||||
|
@ -79,9 +79,6 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
/// Implements <see cref="Count{T}"/> with a sequential search.
|
||||
/// </summary>
|
||||
[Pure]
|
||||
#if NETCOREAPP3_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
private static nint CountSequential<T>(ref T r0, nint length, T value)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
|
@ -132,9 +129,6 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
/// Implements <see cref="Count{T}"/> with a vectorized search.
|
||||
/// </summary>
|
||||
[Pure]
|
||||
#if NETCOREAPP3_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
private static nint CountSimd<T>(ref T r0, nint length, T value)
|
||||
where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
|
@ -161,6 +155,67 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
|
||||
var partials = Vector<T>.Zero;
|
||||
|
||||
// Unrolled vectorized loop, with 8 unrolled iterations. We only run this when the
|
||||
// current type T is at least 2 bytes in size, otherwise the average chunk length
|
||||
// would always be too small to be able to trigger the unrolled loop, and the overall
|
||||
// performance would just be slightly worse due to the additional conditional branches.
|
||||
if (typeof(T) != typeof(sbyte))
|
||||
{
|
||||
while (chunkLength >= Vector<T>.Count * 8)
|
||||
{
|
||||
ref T ri0 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 0));
|
||||
var vi0 = Unsafe.As<T, Vector<T>>(ref ri0);
|
||||
var ve0 = Vector.Equals(vi0, vc);
|
||||
|
||||
partials -= ve0;
|
||||
|
||||
ref T ri1 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 1));
|
||||
var vi1 = Unsafe.As<T, Vector<T>>(ref ri1);
|
||||
var ve1 = Vector.Equals(vi1, vc);
|
||||
|
||||
partials -= ve1;
|
||||
|
||||
ref T ri2 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 2));
|
||||
var vi2 = Unsafe.As<T, Vector<T>>(ref ri2);
|
||||
var ve2 = Vector.Equals(vi2, vc);
|
||||
|
||||
partials -= ve2;
|
||||
|
||||
ref T ri3 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 3));
|
||||
var vi3 = Unsafe.As<T, Vector<T>>(ref ri3);
|
||||
var ve3 = Vector.Equals(vi3, vc);
|
||||
|
||||
partials -= ve3;
|
||||
|
||||
ref T ri4 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 4));
|
||||
var vi4 = Unsafe.As<T, Vector<T>>(ref ri4);
|
||||
var ve4 = Vector.Equals(vi4, vc);
|
||||
|
||||
partials -= ve4;
|
||||
|
||||
ref T ri5 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 5));
|
||||
var vi5 = Unsafe.As<T, Vector<T>>(ref ri5);
|
||||
var ve5 = Vector.Equals(vi5, vc);
|
||||
|
||||
partials -= ve5;
|
||||
|
||||
ref T ri6 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 6));
|
||||
var vi6 = Unsafe.As<T, Vector<T>>(ref ri6);
|
||||
var ve6 = Vector.Equals(vi6, vc);
|
||||
|
||||
partials -= ve6;
|
||||
|
||||
ref T ri7 = ref Unsafe.Add(ref r0, offset + (Vector<T>.Count * 7));
|
||||
var vi7 = Unsafe.As<T, Vector<T>>(ref ri7);
|
||||
var ve7 = Vector.Equals(vi7, vc);
|
||||
|
||||
partials -= ve7;
|
||||
|
||||
chunkLength -= Vector<T>.Count * 8;
|
||||
offset += Vector<T>.Count * 8;
|
||||
}
|
||||
}
|
||||
|
||||
while (chunkLength >= Vector<T>.Count)
|
||||
{
|
||||
ref T ri = ref Unsafe.Add(ref r0, offset);
|
||||
|
@ -242,28 +297,22 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
private static unsafe nint GetUpperBound<T>()
|
||||
where T : unmanaged
|
||||
{
|
||||
if (typeof(T) == typeof(byte) ||
|
||||
typeof(T) == typeof(sbyte) ||
|
||||
typeof(T) == typeof(bool))
|
||||
if (typeof(T) == typeof(sbyte))
|
||||
{
|
||||
return sbyte.MaxValue;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(char) ||
|
||||
typeof(T) == typeof(ushort) ||
|
||||
typeof(T) == typeof(short))
|
||||
if (typeof(T) == typeof(short))
|
||||
{
|
||||
return short.MaxValue;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(int) ||
|
||||
typeof(T) == typeof(uint))
|
||||
if (typeof(T) == typeof(int))
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(long) ||
|
||||
typeof(T) == typeof(ulong))
|
||||
if (typeof(T) == typeof(long))
|
||||
{
|
||||
if (sizeof(nint) == sizeof(int))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// 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.
|
||||
|
||||
|
@ -21,9 +21,6 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
/// <param name="length">The number of items to hash.</param>
|
||||
/// <returns>The Djb2 value for the input sequence of items.</returns>
|
||||
[Pure]
|
||||
#if NETCOREAPP3_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static int GetDjb2HashCode<T>(ref T r0, nint length)
|
||||
where T : notnull
|
||||
{
|
||||
|
@ -87,9 +84,6 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
|
|||
/// faster than <see cref="GetDjb2HashCode{T}"/>, as it can parallelize much of the workload.
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
#if NETCOREAPP3_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static unsafe int GetDjb2LikeByteHash(ref byte r0, nint length)
|
||||
{
|
||||
int hash = 5381;
|
||||
|
|
|
@ -17,6 +17,8 @@ using Microsoft.Toolkit.HighPerformance.Memory.Internals;
|
|||
using Microsoft.Toolkit.HighPerformance.Memory.Views;
|
||||
using static Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
|
||||
|
||||
#pragma warning disable CA2231
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Memory
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -601,7 +603,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
#if SPAN_RUNTIME_SUPPORT
|
||||
if (this.instance is MemoryManager<T> memoryManager)
|
||||
|
@ -738,7 +740,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
/// <returns>A <see cref="MemoryHandle"/> instance wrapping the pinned handle.</returns>
|
||||
public unsafe MemoryHandle Pin()
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
if (this.instance is MemoryManager<T> memoryManager)
|
||||
{
|
||||
|
@ -863,7 +865,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
#if !NETSTANDARD1_4
|
||||
return HashCode.Combine(
|
||||
|
|
|
@ -17,6 +17,8 @@ using Microsoft.Toolkit.HighPerformance.Memory.Internals;
|
|||
using Microsoft.Toolkit.HighPerformance.Memory.Views;
|
||||
using static Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
|
||||
|
||||
#pragma warning disable CA2231
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Memory
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -615,7 +617,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
#if SPAN_RUNTIME_SUPPORT
|
||||
if (this.instance is MemoryManager<T> memoryManager)
|
||||
|
@ -753,7 +755,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
/// <returns>A <see cref="MemoryHandle"/> instance wrapping the pinned handle.</returns>
|
||||
public unsafe MemoryHandle Pin()
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
if (this.instance is MemoryManager<T> memoryManager)
|
||||
{
|
||||
|
@ -876,7 +878,7 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (!(this.instance is null))
|
||||
if (this.instance is not null)
|
||||
{
|
||||
#if !NETSTANDARD1_4
|
||||
return HashCode.Combine(
|
||||
|
|
|
@ -15,6 +15,8 @@ using Microsoft.Toolkit.HighPerformance.Memory.Views;
|
|||
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
|
||||
#endif
|
||||
|
||||
#pragma warning disable CS0809, CA1065
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Memory
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -943,7 +945,6 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
return array;
|
||||
}
|
||||
|
||||
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
|
||||
/// <inheritdoc cref="ReadOnlySpan{T}.Equals(object)"/>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
|
||||
|
@ -959,7 +960,6 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
{
|
||||
throw new NotSupportedException("Microsoft.Toolkit.HighPerformance.ReadOnlySpan2D<T>.GetHashCode() is not supported");
|
||||
}
|
||||
#pragma warning restore CS0809
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
|
|
|
@ -15,6 +15,8 @@ using Microsoft.Toolkit.HighPerformance.Memory.Views;
|
|||
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
|
||||
#endif
|
||||
|
||||
#pragma warning disable CS0809, CA1065
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Memory
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -1093,7 +1095,6 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
return array;
|
||||
}
|
||||
|
||||
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
|
||||
/// <inheritdoc cref="Span{T}.Equals(object)"/>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
|
||||
|
@ -1109,7 +1110,6 @@ namespace Microsoft.Toolkit.HighPerformance.Memory
|
|||
{
|
||||
throw new NotSupportedException("Microsoft.Toolkit.HighPerformance.Span2D<T>.GetHashCode() is not supported");
|
||||
}
|
||||
#pragma warning restore CS0809
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard1.4;netstandard2.0;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard1.4;netstandard2.0;netstandard2.1;netcoreapp2.1;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
@ -75,6 +75,11 @@
|
|||
<DefineConstants>NETSTANDARD2_1_OR_GREATER;SPAN_RUNTIME_SUPPORT</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition=" '$(TargetFramework)' == 'net5.0' ">
|
||||
<PropertyGroup>
|
||||
<DefineConstants>NETSTANDARD2_1_OR_GREATER;SPAN_RUNTIME_SUPPORT</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
|
||||
|
@ -82,11 +87,12 @@
|
|||
<PropertyGroup>
|
||||
|
||||
<!-- NETCORE_RUNTIME: to avoid issues with APIs that assume a specific memory layout, we define a
|
||||
.NET Core runtime constant to indicate the either .NET Core 2.1 or .NET Core 3.1. These are
|
||||
.NET Core runtime constant to indicate either .NET Core 2.1 or .NET Core 3.1. These are
|
||||
runtimes with the same overall memory layout for objects (in particular: strings, SZ arrays,
|
||||
and 2D arrays). We can use this constant to make sure that APIs that are exclusively available
|
||||
for .NET Standard targets do not make any assumption of any internals of the runtime being
|
||||
actually used by the consumers. -->
|
||||
and ND arrays). We can use this constant to make sure that APIs that are exclusively available
|
||||
for .NET Standard targets do not make any assumtpion of any internals of the runtime being
|
||||
actually used by the consumers. .NET 5.0 would fall into this category as well, but we don't
|
||||
need to include that target as it offers APIs that don't require runtime-based workarounds.-->
|
||||
<DefineConstants>NETSTANDARD2_1_OR_GREATER;SPAN_RUNTIME_SUPPORT;NETCORE_RUNTIME</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Microsoft.Toolkit.HighPerformance
|
|||
/// <summary>
|
||||
/// Gets a value indicating whether or not the current <see cref="NullableReadOnlyRef{T}"/> instance wraps a valid reference that can be accessed.
|
||||
/// </summary>
|
||||
public bool HasValue
|
||||
public unsafe bool HasValue
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
|
@ -63,7 +63,7 @@ namespace Microsoft.Toolkit.HighPerformance
|
|||
// See comment in NullableRef<T> about this
|
||||
byte length = unchecked((byte)this.span.Length);
|
||||
|
||||
return Unsafe.As<byte, bool>(ref length);
|
||||
return *(bool*)&length;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace Microsoft.Toolkit.HighPerformance
|
|||
/// <summary>
|
||||
/// Gets a value indicating whether or not the current <see cref="NullableRef{T}"/> instance wraps a valid reference that can be accessed.
|
||||
/// </summary>
|
||||
public bool HasValue
|
||||
public unsafe bool HasValue
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
|
@ -67,7 +67,7 @@ namespace Microsoft.Toolkit.HighPerformance
|
|||
// This results in a single movzx instruction on x86-64.
|
||||
byte length = unchecked((byte)Span.Length);
|
||||
|
||||
return Unsafe.As<byte, bool>(ref length);
|
||||
return *(bool*)&length;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// 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.Runtime.CompilerServices;
|
||||
|
||||
// We can suppress the .init flag for local variables for the entire module.
|
||||
// This doesn't affect the correctness of methods in this assembly, as none of them
|
||||
// are relying on the JIT ensuring that all local memory is zeroed out to work. Doing
|
||||
// this can provide some minor performance benefits, depending on the workload.
|
||||
[module: SkipLocalsInit]
|
|
@ -0,0 +1,76 @@
|
|||
// 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.
|
||||
|
||||
#if SPAN_RUNTIME_SUPPORT
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Streams
|
||||
{
|
||||
/// <inheritdoc cref="IBufferWriterStream{TWriter}"/>
|
||||
internal sealed partial class IBufferWriterStream<TWriter>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override void CopyTo(Stream destination, int bufferSize)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return new ValueTask(Task.FromCanceled(cancellationToken));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Write(buffer.Span);
|
||||
|
||||
return default;
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
return new ValueTask(Task.FromCanceled(e.CancellationToken));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ValueTask(Task.FromException(e));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Write(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
MemoryStream.ValidateDisposed(this.disposed);
|
||||
|
||||
Span<byte> destination = this.bufferWriter.GetSpan(buffer.Length);
|
||||
|
||||
if (!buffer.TryCopyTo(destination))
|
||||
{
|
||||
MemoryStream.ThrowArgumentExceptionForEndOfStreamOnWrite();
|
||||
}
|
||||
|
||||
this.bufferWriter.Advance(buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
// 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.Buffers;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Streams
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="Stream"/> implementation wrapping an <see cref="IBufferWriter{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="TWriter">The type of buffer writer to use.</typeparam>
|
||||
internal sealed partial class IBufferWriterStream<TWriter> : Stream
|
||||
where TWriter : struct, IBufferWriter<byte>
|
||||
{
|
||||
/// <summary>
|
||||
/// The target <typeparamref name="TWriter"/> instance to use.
|
||||
/// </summary>
|
||||
private readonly TWriter bufferWriter;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether or not the current instance has been disposed
|
||||
/// </summary>
|
||||
private bool disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IBufferWriterStream{TWriter}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="bufferWriter">The target <see cref="IBufferWriter{T}"/> instance to use.</param>
|
||||
public IBufferWriterStream(TWriter bufferWriter)
|
||||
{
|
||||
this.bufferWriter = bufferWriter;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanRead => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanSeek => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanWrite
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => !this.disposed;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override long Length => throw MemoryStream.GetNotSupportedException();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override long Position
|
||||
{
|
||||
get => throw MemoryStream.GetNotSupportedException();
|
||||
set => throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return Task.FromCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<int> ReadAsync(byte[]? buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task WriteAsync(byte[]? buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return Task.FromCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Write(buffer, offset, count);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
return Task.FromCanceled(e.CancellationToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Task.FromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int Read(byte[]? buffer, int offset, int count)
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int ReadByte()
|
||||
{
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Write(byte[]? buffer, int offset, int count)
|
||||
{
|
||||
MemoryStream.ValidateDisposed(this.disposed);
|
||||
MemoryStream.ValidateBuffer(buffer, offset, count);
|
||||
|
||||
Span<byte>
|
||||
source = buffer.AsSpan(offset, count),
|
||||
destination = this.bufferWriter.GetSpan(count);
|
||||
|
||||
if (!source.TryCopyTo(destination))
|
||||
{
|
||||
MemoryStream.ThrowArgumentExceptionForEndOfStreamOnWrite();
|
||||
}
|
||||
|
||||
this.bufferWriter.Advance(count);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
MemoryStream.ValidateDisposed(this.disposed);
|
||||
|
||||
this.bufferWriter.GetSpan(1)[0] = value;
|
||||
|
||||
this.bufferWriter.Advance(1);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,23 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
|
|||
/// </summary>
|
||||
internal static partial class MemoryStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a standard <see cref="NotSupportedException"/> instance for a stream.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="NotSupportedException"/> with the standard text.</returns>
|
||||
public static Exception GetNotSupportedException()
|
||||
{
|
||||
return new NotSupportedException("The requested operation is not supported for this stream.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws a <see cref="NotSupportedException"/> when trying to perform a not supported operation.
|
||||
/// </summary>
|
||||
public static void ThrowNotSupportedException()
|
||||
{
|
||||
throw GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an <see cref="ArgumentException"/> when trying to write too many bytes to the target stream.
|
||||
/// </summary>
|
||||
|
@ -20,14 +37,6 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
|
|||
throw new ArgumentException("The current stream can't contain the requested input data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws a <see cref="NotSupportedException"/> when trying to set the length of the stream.
|
||||
/// </summary>
|
||||
public static void ThrowNotSupportedExceptionForSetLength()
|
||||
{
|
||||
throw new NotSupportedException("Setting the length is not supported for this stream.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an <see cref="ArgumentException"/> when using an invalid seek mode.
|
||||
/// </summary>
|
||||
|
@ -77,14 +86,6 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
|
|||
throw new ArgumentException("The sum of offset and count can't be larger than the buffer length.", "buffer");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws a <see cref="NotSupportedException"/> when trying to write on a readonly stream.
|
||||
/// </summary>
|
||||
private static void ThrowNotSupportedExceptionForCanWrite()
|
||||
{
|
||||
throw new NotSupportedException("The current stream doesn't support writing.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an <see cref="ObjectDisposedException"/> when using a disposed <see cref="Stream"/> instance.
|
||||
/// </summary>
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
|
|||
{
|
||||
if (!canWrite)
|
||||
{
|
||||
ThrowNotSupportedExceptionForCanWrite();
|
||||
ThrowNotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
|
|||
/// <inheritdoc/>
|
||||
public sealed override void SetLength(long value)
|
||||
{
|
||||
MemoryStream.ThrowNotSupportedExceptionForSetLength();
|
||||
throw MemoryStream.GetNotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// 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.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Streams.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="IBufferWriter{T}"/> implementation wrapping an <see cref="ArrayPoolBufferWriter{T}"/> instance.
|
||||
/// </summary>
|
||||
internal readonly struct ArrayBufferWriterOwner : IBufferWriter<byte>
|
||||
{
|
||||
/// <summary>
|
||||
/// The wrapped <see cref="ArrayPoolBufferWriter{T}"/> array.
|
||||
/// </summary>
|
||||
private readonly ArrayPoolBufferWriter<byte> writer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArrayBufferWriterOwner"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="writer">The wrapped <see cref="ArrayPoolBufferWriter{T}"/> instance.</param>
|
||||
public ArrayBufferWriterOwner(ArrayPoolBufferWriter<byte> writer)
|
||||
{
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Advance(int count)
|
||||
{
|
||||
this.writer.Advance(count);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory<byte> GetMemory(int sizeHint = 0)
|
||||
{
|
||||
return this.writer.GetMemory(sizeHint);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<byte> GetSpan(int sizeHint = 0)
|
||||
{
|
||||
return this.writer.GetSpan(sizeHint);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// 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.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers;
|
||||
|
||||
namespace Microsoft.Toolkit.HighPerformance.Streams.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="IBufferWriter{T}"/> implementation wrapping an <see cref="IBufferWriter{T}"/> instance.
|
||||
/// </summary>
|
||||
internal readonly struct IBufferWriterOwner : IBufferWriter<byte>
|
||||
{
|
||||
/// <summary>
|
||||
/// The wrapped <see cref="ArrayPoolBufferWriter{T}"/> array.
|
||||
/// </summary>
|
||||
private readonly IBufferWriter<byte> writer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IBufferWriterOwner"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="writer">The wrapped <see cref="IBufferWriter{T}"/> instance.</param>
|
||||
public IBufferWriterOwner(IBufferWriter<byte> writer)
|
||||
{
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Advance(int count)
|
||||
{
|
||||
this.writer.Advance(count);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory<byte> GetMemory(int sizeHint = 0)
|
||||
{
|
||||
return this.writer.GetMemory(sizeHint);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<byte> GetSpan(int sizeHint = 0)
|
||||
{
|
||||
return this.writer.GetSpan(sizeHint);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
<Project Sdk="MSBuild.Sdk.Extras">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard1.4;uap10.0;native;net461;netcoreapp3.1</TargetFrameworks>
|
||||
<!--<TargetFrameworks>netstandard1.4;uap10.0;native;net461;netcoreapp3.1</TargetFrameworks>-->
|
||||
<!-- Removed 'native' target to unblock CI on VS 16.8, tied to changes breaking workaround for https://github.com/NuGet/Home/issues/5154 -->
|
||||
<TargetFrameworks>netstandard1.4;uap10.0;net461;netcoreapp3.1</TargetFrameworks>
|
||||
<DefineConstants>$(DefineConstants);NETFX_CORE</DefineConstants>
|
||||
<Title>Windows Community Toolkit Notifications</Title>
|
||||
<Description>
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Controls
|
|||
public static readonly DependencyProperty TextProperty =
|
||||
DependencyProperty.Register(nameof(Text), typeof(string), typeof(XamlCodeEditor), new PropertyMetadata(string.Empty));
|
||||
|
||||
private ThemeListener _themeListener = new ThemeListener();
|
||||
|
||||
public XamlCodeEditor()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
@ -40,7 +42,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Controls
|
|||
// Highlight Error Line
|
||||
XamlCodeRenderer.Decorations.Add(new IModelDeltaDecoration(
|
||||
range,
|
||||
new IModelDecorationOptions() { IsWholeLine = true, ClassName = _errorStyle, HoverMessage = new string[] { error.Message }.ToMarkdownString() }));
|
||||
new IModelDecorationOptions() { IsWholeLine = true, ClassName = ErrorStyle, HoverMessage = new string[] { error.Message }.ToMarkdownString() }));
|
||||
|
||||
// Show Glyph Icon
|
||||
XamlCodeRenderer.Decorations.Add(new IModelDeltaDecoration(
|
||||
|
@ -121,10 +123,12 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Controls
|
|||
|
||||
public DateTime TimeSampleEditedLast { get; private set; } = DateTime.MinValue;
|
||||
|
||||
private CssLineStyle _errorStyle = new CssLineStyle()
|
||||
private CssLineStyle ErrorStyle
|
||||
{
|
||||
BackgroundColor = new SolidColorBrush(Color.FromArgb(0x00, 0xFF, 0xD6, 0xD6))
|
||||
};
|
||||
get => _themeListener.CurrentTheme.Equals(ApplicationTheme.Light) ?
|
||||
new CssLineStyle() { BackgroundColor = new SolidColorBrush(Color.FromArgb(0x00, 0xFF, 0xD6, 0xD6)) } :
|
||||
new CssLineStyle() { BackgroundColor = new SolidColorBrush(Color.FromArgb(0x00, 0x66, 0x00, 0x00)) };
|
||||
}
|
||||
|
||||
private CssGlyphStyle _errorIconStyle = new CssGlyphStyle()
|
||||
{
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Microsoft.Toolkit.Uwp.SampleApp.Pages;
|
||||
using Microsoft.Toolkit.Uwp.UI.Animations;
|
||||
|
@ -147,7 +148,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
|
|||
ShowSamplePicker(category.Samples, true);
|
||||
|
||||
// Then Focus on Picker
|
||||
DispatcherHelper.ExecuteOnUIThreadAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
|
||||
dispatcherQueue.EnqueueAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
|
||||
}
|
||||
}
|
||||
else if (args.IsSettingsInvoked)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Microsoft.Toolkit.Uwp.UI.Extensions;
|
||||
using Windows.UI.Xaml;
|
||||
|
@ -76,7 +77,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
|
|||
if (e.Key == Windows.System.VirtualKey.Down && SamplePickerGrid.Visibility == Windows.UI.Xaml.Visibility.Visible)
|
||||
{
|
||||
// If we try and navigate down out of the textbox (and there's search results), go to the search results.
|
||||
DispatcherHelper.ExecuteOnUIThreadAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
|
||||
dispatcherQueue.EnqueueAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ using Microsoft.Toolkit.Uwp.Helpers;
|
|||
using Microsoft.Toolkit.Uwp.SampleApp.Pages;
|
||||
using Microsoft.Toolkit.Uwp.UI.Extensions;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
@ -16,6 +15,8 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
|
|||
{
|
||||
public sealed partial class Shell
|
||||
{
|
||||
private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
public static Shell Current { get; private set; }
|
||||
|
||||
public Shell()
|
||||
|
|
|
@ -11,6 +11,7 @@ using Windows.UI.Xaml;
|
|||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Hosting;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Animations.Behaviors
|
||||
{
|
||||
|
@ -238,7 +239,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Behaviors
|
|||
focusedElement = FocusManager.GetFocusedElement();
|
||||
}
|
||||
|
||||
if (focusedElement is UIElement element)
|
||||
// To prevent Popups (Flyouts...) from triggering the autoscroll, we check if the focused element has a valid parent.
|
||||
// Popups have no parents, whereas a normal Item would have the ListView as a parent.
|
||||
if (focusedElement is UIElement element && VisualTreeHelper.GetParent(element) != null)
|
||||
{
|
||||
FrameworkElement header = (FrameworkElement)HeaderElement;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Effects;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Composition;
|
||||
using Windows.UI.Composition.Effects;
|
||||
|
@ -102,7 +102,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations
|
|||
var task = new AnimationTask();
|
||||
task.AnimationSet = animationSet;
|
||||
|
||||
task.Task = DispatcherHelper.ExecuteOnUIThreadAsync(
|
||||
task.Task = visual.DispatcherQueue.EnqueueAsync(
|
||||
() =>
|
||||
{
|
||||
const string sceneName = "PointLightScene";
|
||||
|
@ -184,7 +184,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations
|
|||
}
|
||||
|
||||
pointLights[visual] = pointLight;
|
||||
}, Windows.UI.Core.CoreDispatcherPriority.Normal);
|
||||
});
|
||||
|
||||
animationSet.AddAnimationThroughTask(task);
|
||||
return animationSet;
|
||||
|
|
|
@ -162,10 +162,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions
|
|||
offsetX = offsetX > _maxSpeed ? _maxSpeed : offsetX;
|
||||
offsetY = offsetY > _maxSpeed ? _maxSpeed : offsetY;
|
||||
|
||||
RunInUIThread(dispatcherQueue, () =>
|
||||
{
|
||||
_scrollViewer?.ChangeView(_scrollViewer.HorizontalOffset + offsetX, _scrollViewer.VerticalOffset + offsetY, null, true);
|
||||
});
|
||||
dispatcherQueue.EnqueueAsync(() => _scrollViewer?.ChangeView(_scrollViewer.HorizontalOffset + offsetX, _scrollViewer.VerticalOffset + offsetY, null, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,10 +323,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions
|
|||
|
||||
if (_oldCursorID != cursorID)
|
||||
{
|
||||
RunInUIThread(dispatcherQueue, () =>
|
||||
{
|
||||
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Custom, cursorID);
|
||||
});
|
||||
dispatcherQueue.EnqueueAsync(() => Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Custom, cursorID));
|
||||
|
||||
_oldCursorID = cursorID;
|
||||
}
|
||||
|
@ -366,10 +360,5 @@ namespace Microsoft.Toolkit.Uwp.UI.Extensions
|
|||
|
||||
return isCursorAvailable;
|
||||
}
|
||||
|
||||
private static async void RunInUIThread(DispatcherQueue dispatcherQueue, Action action)
|
||||
{
|
||||
await dispatcherQueue.EnqueueAsync(action, DispatcherQueuePriority.Normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation.Metadata;
|
||||
using Windows.System;
|
||||
|
@ -67,7 +68,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
}))
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("Failed to enqueue the operation"));
|
||||
taskCompletionSource.SetException(GetEnqueueException("Failed to enqueue the operation"));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
|
@ -116,7 +117,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
}))
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("Failed to enqueue the operation"));
|
||||
taskCompletionSource.SetException(GetEnqueueException("Failed to enqueue the operation"));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
|
@ -149,7 +150,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
return awaitableResult;
|
||||
}
|
||||
|
||||
return Task.FromException(new InvalidOperationException("The Task returned by function cannot be null."));
|
||||
return Task.FromException(GetEnqueueException("The Task returned by function cannot be null."));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -173,7 +174,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
else
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
|
||||
taskCompletionSource.SetException(GetEnqueueException("The Task returned by function cannot be null."));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -182,7 +183,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
}))
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("Failed to enqueue the operation"));
|
||||
taskCompletionSource.SetException(GetEnqueueException("Failed to enqueue the operation"));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
|
@ -212,7 +213,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
return awaitableResult;
|
||||
}
|
||||
|
||||
return Task.FromException<T>(new InvalidOperationException("The Task returned by function cannot be null."));
|
||||
return Task.FromException<T>(GetEnqueueException("The Task returned by function cannot be null."));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -236,7 +237,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
else
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
|
||||
taskCompletionSource.SetException(GetEnqueueException("The Task returned by function cannot be null."));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -245,7 +246,7 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
}
|
||||
}))
|
||||
{
|
||||
taskCompletionSource.SetException(new InvalidOperationException("Failed to enqueue the operation"));
|
||||
taskCompletionSource.SetException(GetEnqueueException("Failed to enqueue the operation"));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
|
@ -253,5 +254,16 @@ namespace Microsoft.Toolkit.Uwp.Extensions
|
|||
|
||||
return TryEnqueueAsync(dispatcher, function, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="InvalidOperationException"/> to return when an enqueue operation fails.
|
||||
/// </summary>
|
||||
/// <param name="message">The message of the exception.</param>
|
||||
/// <returns>An <see cref="InvalidOperationException"/> with a specified message.</returns>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static InvalidOperationException GetEnqueueException(string message)
|
||||
{
|
||||
return new InvalidOperationException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#if !NETSTANDARD2_1
|
||||
#if !NETSTANDARD2_1_OR_GREATER
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
/// <summary>
|
||||
/// Applied to a method that will never return under any circumstance.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy of the .NET Standard 2.1 attribute.</remarks>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||
internal sealed class DoesNotReturnAttribute : Attribute
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
||||
#if !NETSTANDARD2_1
|
||||
#if !NETSTANDARD2_1_OR_GREATER
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ namespace System.Diagnostics.CodeAnalysis
|
|||
/// Specifies that a given <see cref="ParameterValue"/> also indicates
|
||||
/// whether the method will not return (eg. throw an exception).
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy of the .NET Standard 2.1 attribute.</remarks>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class DoesNotReturnIfAttribute : Attribute
|
||||
{
|
||||
|
|
|
@ -1,18 +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.
|
||||
|
||||
#if !NETSTANDARD2_1
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that an output may be <see langword="null"/> even if the corresponding type disallows it.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
|
||||
internal sealed class MaybeNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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.
|
||||
|
||||
#if !NETSTANDARD2_1
|
||||
#if !NETSTANDARD2_1_OR_GREATER
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ namespace System.Diagnostics.CodeAnalysis
|
|||
/// Specifies that an output will not be <see langword="null"/> even if the corresponding type allows it.
|
||||
/// Specifies that an input argument was not <see langword="null"/> when the call returns.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy of the .NET Standard 2.1 attribute.</remarks>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
|
||||
internal sealed class NotNullAttribute : Attribute
|
||||
{
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// 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.
|
||||
|
||||
#if !NETSTANDARD2_1_OR_GREATER
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that the output will be non-null if the named parameter is non-null.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
|
||||
internal sealed class NotNullIfNotNullAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotNullIfNotNullAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.</param>
|
||||
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the associated parameter name.
|
||||
/// </summary>
|
||||
public string ParameterName { get; }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,29 @@
|
|||
// 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.
|
||||
|
||||
#if !NETSTANDARD2_1_OR_GREATER
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||
internal sealed class NotNullWhenAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotNullWhenAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="returnValue">The return value condition. If the method returns this value, the associated parameter will not be null.</param>
|
||||
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the annotated variable is not <see langword="null"/>.
|
||||
/// </summary>
|
||||
public bool ReturnValue { get; }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
// 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.
|
||||
|
||||
#if !NET5_0
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to indicate to the compiler that the <c>.locals init</c> flag should not be set in method headers.
|
||||
/// </summary>
|
||||
/// <remarks>Internal copy from the BCL attribute.</remarks>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Module |
|
||||
AttributeTargets.Class |
|
||||
AttributeTargets.Struct |
|
||||
AttributeTargets.Interface |
|
||||
AttributeTargets.Constructor |
|
||||
AttributeTargets.Method |
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Event,
|
||||
Inherited = false)]
|
||||
internal sealed class SkipLocalsInitAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,6 +18,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <typeparam name="TValue">The type of the items in the collection.</typeparam>
|
||||
[DebuggerDisplay("Key = {Key}, Count = {Count}")]
|
||||
public class ObservableGroup<TKey, TValue> : ObservableCollection<TValue>, IGrouping<TKey, TValue>, IReadOnlyObservableGroup
|
||||
where TKey : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// The cached <see cref="PropertyChangedEventArgs"/> for <see cref="Key"/>
|
||||
|
@ -30,7 +31,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <param name="key">The key for the group.</param>
|
||||
public ObservableGroup(TKey key)
|
||||
{
|
||||
Key = key;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -40,7 +41,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
public ObservableGroup(IGrouping<TKey, TValue> grouping)
|
||||
: base(grouping)
|
||||
{
|
||||
Key = grouping.Key;
|
||||
this.key = grouping.Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,7 +52,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
public ObservableGroup(TKey key, IEnumerable<TValue> collection)
|
||||
: base(collection)
|
||||
{
|
||||
Key = key;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
private TKey key;
|
||||
|
@ -64,7 +65,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
get => this.key;
|
||||
set
|
||||
{
|
||||
if (!EqualityComparer<TKey>.Default.Equals(this.key, value))
|
||||
if (!EqualityComparer<TKey>.Default.Equals(this.key!, value))
|
||||
{
|
||||
this.key = value;
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Collections
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -17,6 +16,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <typeparam name="TKey">The type of the group key.</typeparam>
|
||||
/// <typeparam name="TValue">The type of the items in the collection.</typeparam>
|
||||
public sealed class ObservableGroupedCollection<TKey, TValue> : ObservableCollection<ObservableGroup<TKey, TValue>>
|
||||
where TKey : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObservableGroupedCollection{TKey, TValue}"/> class.
|
||||
|
@ -30,7 +30,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// </summary>
|
||||
/// <param name="collection">The initial data to add in the grouped collection.</param>
|
||||
public ObservableGroupedCollection(IEnumerable<IGrouping<TKey, TValue>> collection)
|
||||
: base(collection.Select(c => new ObservableGroup<TKey, TValue>(c)))
|
||||
: base(collection.Select(static c => new ObservableGroup<TKey, TValue>(c)))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -40,11 +40,11 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <param name="list">The resulting <see cref="List{T}"/>, if one was in use.</param>
|
||||
/// <returns>Whether or not a <see cref="List{T}"/> instance has been found.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal bool TryGetList(out List<ObservableGroup<TKey, TValue>>? list)
|
||||
internal bool TryGetList([NotNullWhen(true)] out List<ObservableGroup<TKey, TValue>>? list)
|
||||
{
|
||||
list = Items as List<ObservableGroup<TKey, TValue>>;
|
||||
|
||||
return !(list is null);
|
||||
return list is not null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ using System.Diagnostics.Contracts;
|
|||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Collections
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -28,11 +26,17 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <exception cref="InvalidOperationException">The target group does not exist.</exception>
|
||||
[Pure]
|
||||
public static ObservableGroup<TKey, TValue> First<TKey, TValue>(this ObservableGroupedCollection<TKey, TValue> source, TKey key)
|
||||
where TKey : notnull
|
||||
{
|
||||
ObservableGroup<TKey, TValue>? group = source.FirstOrDefault(key);
|
||||
|
||||
if (group is null)
|
||||
{
|
||||
static void ThrowArgumentExceptionForKeyNotFound()
|
||||
{
|
||||
throw new InvalidOperationException("The requested key was not present in the collection");
|
||||
}
|
||||
|
||||
ThrowArgumentExceptionForKeyNotFound();
|
||||
}
|
||||
|
||||
|
@ -49,10 +53,11 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <returns>The first group matching <paramref name="key"/> or null.</returns>
|
||||
[Pure]
|
||||
public static ObservableGroup<TKey, TValue>? FirstOrDefault<TKey, TValue>(this ObservableGroupedCollection<TKey, TValue> source, TKey key)
|
||||
where TKey : notnull
|
||||
{
|
||||
if (source.TryGetList(out var list))
|
||||
{
|
||||
foreach (var group in list!)
|
||||
foreach (var group in list)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
|
@ -63,19 +68,16 @@ namespace Microsoft.Toolkit.Collections
|
|||
return null;
|
||||
}
|
||||
|
||||
// Fallback method
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static ObservableGroup<TKey, TValue>? FirstOrDefaultWithLinq(ObservableGroupedCollection<TKey, TValue> source, TKey key)
|
||||
{
|
||||
return source.FirstOrDefault(group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
|
||||
}
|
||||
|
||||
return FirstOrDefaultWithLinq(source, key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slow path for <see cref="First{TKey,TValue}"/>.
|
||||
/// </summary>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static ObservableGroup<TKey, TValue>? FirstOrDefaultWithLinq<TKey, TValue>(
|
||||
ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key)
|
||||
=> source.FirstOrDefault(group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
|
||||
|
||||
/// <summary>
|
||||
/// Return the element at position <paramref name="index"/> from the first group with <paramref name="key"/> key.
|
||||
/// </summary>
|
||||
|
@ -92,6 +94,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
int index)
|
||||
where TKey : notnull
|
||||
=> source.First(key)[index];
|
||||
|
||||
/// <summary>
|
||||
|
@ -104,17 +107,18 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <param name="index">The index of the item from the targeted group.</param>
|
||||
/// <returns>The element or default(TValue) if it does not exist.</returns>
|
||||
[Pure]
|
||||
public static TValue ElementAtOrDefault<TKey, TValue>(
|
||||
public static TValue? ElementAtOrDefault<TKey, TValue>(
|
||||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
int index)
|
||||
where TKey : notnull
|
||||
{
|
||||
var group = source.FirstOrDefault(key);
|
||||
|
||||
if (group is null ||
|
||||
(uint)index >= (uint)group.Count)
|
||||
{
|
||||
return default!;
|
||||
return default;
|
||||
}
|
||||
|
||||
return group[index];
|
||||
|
@ -133,6 +137,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
TValue value)
|
||||
where TKey : notnull
|
||||
=> AddGroup(source, key, new[] { value });
|
||||
|
||||
/// <summary>
|
||||
|
@ -148,6 +153,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
params TValue[] collection)
|
||||
where TKey : notnull
|
||||
=> source.AddGroup(key, (IEnumerable<TValue>)collection);
|
||||
|
||||
/// <summary>
|
||||
|
@ -163,6 +169,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
IEnumerable<TValue> collection)
|
||||
where TKey : notnull
|
||||
{
|
||||
var group = new ObservableGroup<TKey, TValue>(key, collection);
|
||||
source.Add(group);
|
||||
|
@ -184,6 +191,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
TValue item)
|
||||
where TKey : notnull
|
||||
{
|
||||
var group = source.FirstOrDefault(key);
|
||||
|
||||
|
@ -215,6 +223,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
TKey key,
|
||||
int index,
|
||||
TValue item)
|
||||
where TKey : notnull
|
||||
{
|
||||
var existingGroup = source.First(key);
|
||||
existingGroup.Insert(index, item);
|
||||
|
@ -239,6 +248,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
TKey key,
|
||||
int index,
|
||||
TValue item)
|
||||
where TKey : notnull
|
||||
{
|
||||
var existingGroup = source.First(key);
|
||||
existingGroup[index] = item;
|
||||
|
@ -257,11 +267,12 @@ namespace Microsoft.Toolkit.Collections
|
|||
public static void RemoveGroup<TKey, TValue>(
|
||||
this ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key)
|
||||
where TKey : notnull
|
||||
{
|
||||
if (source.TryGetList(out var list))
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var group in list!)
|
||||
foreach (var group in list)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
|
@ -275,26 +286,24 @@ namespace Microsoft.Toolkit.Collections
|
|||
}
|
||||
else
|
||||
{
|
||||
RemoveGroupWithLinq(source, key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slow path for <see cref="RemoveGroup{TKey,TValue}"/>.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static void RemoveGroupWithLinq<TKey, TValue>(ObservableGroupedCollection<TKey, TValue> source, TKey key)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
// Fallback method
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void RemoveGroupWithLinq(ObservableGroupedCollection<TKey, TValue> source, TKey key)
|
||||
{
|
||||
source.RemoveAt(index);
|
||||
return;
|
||||
var index = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
source.RemoveAt(index);
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
RemoveGroupWithLinq(source, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,11 +322,12 @@ namespace Microsoft.Toolkit.Collections
|
|||
TKey key,
|
||||
TValue item,
|
||||
bool removeGroupIfEmpty = true)
|
||||
where TKey : notnull
|
||||
{
|
||||
if (source.TryGetList(out var list))
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var group in list!)
|
||||
foreach (var group in list)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
|
@ -336,36 +346,34 @@ namespace Microsoft.Toolkit.Collections
|
|||
}
|
||||
else
|
||||
{
|
||||
RemoveItemWithLinq(source, key, item, removeGroupIfEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slow path for <see cref="RemoveItem{TKey,TValue}"/>.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static void RemoveItemWithLinq<TKey, TValue>(
|
||||
ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
TValue item,
|
||||
bool removeGroupIfEmpty)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
// Fallback method
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void RemoveItemWithLinq(
|
||||
ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
TValue item,
|
||||
bool removeGroupIfEmpty)
|
||||
{
|
||||
if (group.Remove(item) &&
|
||||
removeGroupIfEmpty &&
|
||||
group.Count == 0)
|
||||
var index = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
source.RemoveAt(index);
|
||||
}
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
if (group.Remove(item) &&
|
||||
removeGroupIfEmpty &&
|
||||
group.Count == 0)
|
||||
{
|
||||
source.RemoveAt(index);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
RemoveItemWithLinq(source, key, item, removeGroupIfEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,11 +393,12 @@ namespace Microsoft.Toolkit.Collections
|
|||
TKey key,
|
||||
int index,
|
||||
bool removeGroupIfEmpty = true)
|
||||
where TKey : notnull
|
||||
{
|
||||
if (source.TryGetList(out var list))
|
||||
{
|
||||
var groupIndex = 0;
|
||||
foreach (var group in list!)
|
||||
foreach (var group in list)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
|
@ -408,45 +417,35 @@ namespace Microsoft.Toolkit.Collections
|
|||
}
|
||||
else
|
||||
{
|
||||
// Fallback method
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void RemoveItemAtWithLinq(
|
||||
ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
int index,
|
||||
bool removeGroupIfEmpty)
|
||||
{
|
||||
var groupIndex = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
group.RemoveAt(index);
|
||||
|
||||
if (removeGroupIfEmpty && group.Count == 0)
|
||||
{
|
||||
source.RemoveAt(groupIndex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveItemAtWithLinq(source, key, index, removeGroupIfEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slow path for <see cref="RemoveItemAt{TKey,TValue}"/>.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static void RemoveItemAtWithLinq<TKey, TValue>(
|
||||
ObservableGroupedCollection<TKey, TValue> source,
|
||||
TKey key,
|
||||
int index,
|
||||
bool removeGroupIfEmpty)
|
||||
{
|
||||
var groupIndex = 0;
|
||||
foreach (var group in source)
|
||||
{
|
||||
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
|
||||
{
|
||||
group.RemoveAt(index);
|
||||
|
||||
if (removeGroupIfEmpty && group.Count == 0)
|
||||
{
|
||||
source.RemoveAt(groupIndex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
groupIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws a new <see cref="InvalidOperationException"/> when a key is not found.
|
||||
/// </summary>
|
||||
private static void ThrowArgumentExceptionForKeyNotFound()
|
||||
{
|
||||
throw new InvalidOperationException("The requested key was not present in the collection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <typeparam name="TKey">The type of the group key.</typeparam>
|
||||
/// <typeparam name="TValue">The type of the items in the collection.</typeparam>
|
||||
public sealed class ReadOnlyObservableGroup<TKey, TValue> : ReadOnlyObservableCollection<TValue>, IGrouping<TKey, TValue>, IReadOnlyObservableGroup
|
||||
where TKey : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReadOnlyObservableGroup{TKey, TValue}"/> class.
|
||||
|
|
|
@ -17,15 +17,16 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// <typeparam name="TKey">The type of the group key.</typeparam>
|
||||
/// <typeparam name = "TValue" > The type of the items in the collection.</typeparam>
|
||||
public sealed class ReadOnlyObservableGroupedCollection<TKey, TValue> : ReadOnlyObservableCollection<ReadOnlyObservableGroup<TKey, TValue>>
|
||||
where TKey : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReadOnlyObservableGroupedCollection{TKey, TValue}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="collection">The source collection to wrap.</param>
|
||||
public ReadOnlyObservableGroupedCollection(ObservableGroupedCollection<TKey, TValue> collection)
|
||||
: this(collection.Select(g => new ReadOnlyObservableGroup<TKey, TValue>(g)))
|
||||
: this(collection.Select(static g => new ReadOnlyObservableGroup<TKey, TValue>(g)))
|
||||
{
|
||||
((INotifyCollectionChanged)collection).CollectionChanged += this.OnSourceCollectionChanged;
|
||||
((INotifyCollectionChanged)collection).CollectionChanged += OnSourceCollectionChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -42,14 +43,14 @@ namespace Microsoft.Toolkit.Collections
|
|||
/// </summary>
|
||||
/// <param name="collection">The initial data to add in the grouped collection.</param>
|
||||
public ReadOnlyObservableGroupedCollection(IEnumerable<IGrouping<TKey, TValue>> collection)
|
||||
: this(collection.Select(g => new ReadOnlyObservableGroup<TKey, TValue>(g.Key, g)))
|
||||
: this(collection.Select(static g => new ReadOnlyObservableGroup<TKey, TValue>(g.Key, g)))
|
||||
{
|
||||
}
|
||||
|
||||
private void OnSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
private void OnSourceCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
// Even if the NotifyCollectionChangedEventArgs allows multiple items, the actual implementation is only
|
||||
// reporting the changes one by one. We consider only this case for now.
|
||||
// Even if NotifyCollectionChangedEventArgs allows multiple items, the actual implementation
|
||||
// is only reporting the changes one by one. We consider only this case for now.
|
||||
if (e.OldItems?.Count > 1 || e.NewItems?.Count > 1)
|
||||
{
|
||||
static void ThrowNotSupportedException()
|
||||
|
@ -64,23 +65,33 @@ namespace Microsoft.Toolkit.Collections
|
|||
ThrowNotSupportedException();
|
||||
}
|
||||
|
||||
var newItem = e.NewItems?.Cast<ObservableGroup<TKey, TValue>>()?.FirstOrDefault();
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
Items.Insert(e.NewStartingIndex, new ReadOnlyObservableGroup<TKey, TValue>(newItem));
|
||||
case NotifyCollectionChangedAction.Add or NotifyCollectionChangedAction.Replace:
|
||||
|
||||
// We only need to find the new item if the operation is either add or remove. In this
|
||||
// case we just directly find the first item that was modified, or throw if it's not present.
|
||||
// This normally never happens anyway - add and replace should always have a target element.
|
||||
ObservableGroup<TKey, TValue> newItem = e.NewItems!.Cast<ObservableGroup<TKey, TValue>>().First();
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
Items.Insert(e.NewStartingIndex, new ReadOnlyObservableGroup<TKey, TValue>(newItem));
|
||||
}
|
||||
else
|
||||
{
|
||||
Items[e.OldStartingIndex] = new ReadOnlyObservableGroup<TKey, TValue>(newItem);
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
|
||||
// Our inner Items list is our own ObservableCollection<ReadOnlyObservableGroup<TKey, TValue>> so we can safely cast Items to its concrete type here.
|
||||
((ObservableCollection<ReadOnlyObservableGroup<TKey, TValue>>)Items).Move(e.OldStartingIndex, e.NewStartingIndex);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
Items.RemoveAt(e.OldStartingIndex);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
Items[e.OldStartingIndex] = new ReadOnlyObservableGroup<TKey, TValue>(newItem);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
Items.Clear();
|
||||
break;
|
||||
|
|
|
@ -9,8 +9,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -6,8 +6,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -11,8 +11,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,8 +8,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -6,8 +6,6 @@ using System;
|
|||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -6,8 +6,6 @@ using System;
|
|||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -6,7 +6,7 @@ using System;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable CS8777
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
|
@ -43,9 +43,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
{
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
#pragma warning disable CS8777 // Does not return when text is null
|
||||
return;
|
||||
#pragma warning restore CS8777
|
||||
}
|
||||
|
||||
ThrowHelper.ThrowArgumentExceptionForIsNotNullOrEmpty(text, name);
|
||||
|
@ -97,9 +95,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
{
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
#pragma warning disable CS8777 // Does not return when text is null
|
||||
return;
|
||||
#pragma warning restore CS8777
|
||||
}
|
||||
|
||||
ThrowHelper.ThrowArgumentExceptionForIsNotNullOrWhiteSpace(text, name);
|
||||
|
@ -117,9 +113,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
{
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
#pragma warning disable CS8777 // Does not return when text is null
|
||||
return;
|
||||
#pragma warning restore CS8777
|
||||
}
|
||||
|
||||
ThrowHelper.ThrowArgumentExceptionForIsNotNullOrWhiteSpace(text, name);
|
||||
|
|
|
@ -6,8 +6,6 @@ using System;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -10,8 +10,6 @@ using System.Runtime.CompilerServices;
|
|||
using Microsoft.Toolkit.Extensions;
|
||||
#endif
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -70,7 +68,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
public static void IsNotNull<T>([NotNull] T? value, string name)
|
||||
where T : class
|
||||
{
|
||||
if (!(value is null))
|
||||
if (value is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -90,7 +88,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
public static void IsNotNull<T>([NotNull] T? value, string name)
|
||||
where T : struct
|
||||
{
|
||||
if (!(value is null))
|
||||
if (value is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -198,7 +196,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void IsNotAssignableToType<T>(object value, string name)
|
||||
{
|
||||
if (!(value is T))
|
||||
if (value is not T)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,8 +7,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,8 +7,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,8 +8,6 @@ using System.IO;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -6,8 +6,6 @@ using System;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,8 +8,6 @@ using System.Runtime.CompilerServices;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,8 +8,6 @@ using System.Diagnostics.Contracts;
|
|||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Toolkit.Extensions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -11,8 +11,6 @@ using System.Runtime.InteropServices;
|
|||
#endif
|
||||
using System.Threading;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -40,7 +38,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArrayTypeMismatchException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArrayTypeMismatchException<T>(string message)
|
||||
public static T ThrowArrayTypeMismatchException<T>(string? message)
|
||||
{
|
||||
throw new ArrayTypeMismatchException(message);
|
||||
}
|
||||
|
@ -54,7 +52,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArrayTypeMismatchException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArrayTypeMismatchException<T>(string message, Exception innerException)
|
||||
public static T ThrowArrayTypeMismatchException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArrayTypeMismatchException(message, innerException);
|
||||
}
|
||||
|
@ -79,7 +77,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentException<T>(string message)
|
||||
public static T ThrowArgumentException<T>(string? message)
|
||||
{
|
||||
throw new ArgumentException(message);
|
||||
}
|
||||
|
@ -93,7 +91,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentException<T>(string message, Exception innerException)
|
||||
public static T ThrowArgumentException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentException(message, innerException);
|
||||
}
|
||||
|
@ -107,7 +105,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentException<T>(string name, string message)
|
||||
public static T ThrowArgumentException<T>(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentException(message, name);
|
||||
}
|
||||
|
@ -122,7 +120,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentException<T>(string name, string message, Exception innerException)
|
||||
public static T ThrowArgumentException<T>(string? name, string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentException(message, name, innerException);
|
||||
}
|
||||
|
@ -147,7 +145,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentNullException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentNullException<T>(string name)
|
||||
public static T ThrowArgumentNullException<T>(string? name)
|
||||
{
|
||||
throw new ArgumentNullException(name);
|
||||
}
|
||||
|
@ -161,7 +159,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentNullException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentNullException<T>(string name, Exception innerException)
|
||||
public static T ThrowArgumentNullException<T>(string? name, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentNullException(name, innerException);
|
||||
}
|
||||
|
@ -175,7 +173,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentNullException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentNullException<T>(string name, string message)
|
||||
public static T ThrowArgumentNullException<T>(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentNullException(name, message);
|
||||
}
|
||||
|
@ -200,7 +198,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string name)
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string? name)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name);
|
||||
}
|
||||
|
@ -214,7 +212,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string name, Exception innerException)
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string? name, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, innerException);
|
||||
}
|
||||
|
@ -228,7 +226,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string name, string message)
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, message);
|
||||
}
|
||||
|
@ -243,7 +241,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string name, object value, string message)
|
||||
public static T ThrowArgumentOutOfRangeException<T>(string? name, object? value, string? message)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, value, message);
|
||||
}
|
||||
|
@ -269,7 +267,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="COMException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowCOMException<T>(string message)
|
||||
public static T ThrowCOMException<T>(string? message)
|
||||
{
|
||||
throw new COMException(message);
|
||||
}
|
||||
|
@ -283,7 +281,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="COMException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowCOMException<T>(string message, Exception innerException)
|
||||
public static T ThrowCOMException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new COMException(message, innerException);
|
||||
}
|
||||
|
@ -297,7 +295,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="COMException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowCOMException<T>(string message, int error)
|
||||
public static T ThrowCOMException<T>(string? message, int error)
|
||||
{
|
||||
throw new COMException(message, error);
|
||||
}
|
||||
|
@ -322,7 +320,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ExternalException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowExternalException<T>(string message)
|
||||
public static T ThrowExternalException<T>(string? message)
|
||||
{
|
||||
throw new ExternalException(message);
|
||||
}
|
||||
|
@ -336,7 +334,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ExternalException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowExternalException<T>(string message, Exception innerException)
|
||||
public static T ThrowExternalException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ExternalException(message, innerException);
|
||||
}
|
||||
|
@ -350,7 +348,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ExternalException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowExternalException<T>(string message, int error)
|
||||
public static T ThrowExternalException<T>(string? message, int error)
|
||||
{
|
||||
throw new ExternalException(message, error);
|
||||
}
|
||||
|
@ -376,7 +374,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="FormatException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowFormatException<T>(string message)
|
||||
public static T ThrowFormatException<T>(string? message)
|
||||
{
|
||||
throw new FormatException(message);
|
||||
}
|
||||
|
@ -390,7 +388,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="FormatException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowFormatException<T>(string message, Exception innerException)
|
||||
public static T ThrowFormatException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new FormatException(message, innerException);
|
||||
}
|
||||
|
@ -416,7 +414,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InsufficientMemoryException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInsufficientMemoryException<T>(string message)
|
||||
public static T ThrowInsufficientMemoryException<T>(string? message)
|
||||
{
|
||||
throw new InsufficientMemoryException(message);
|
||||
}
|
||||
|
@ -430,7 +428,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InsufficientMemoryException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInsufficientMemoryException<T>(string message, Exception innerException)
|
||||
public static T ThrowInsufficientMemoryException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InsufficientMemoryException(message, innerException);
|
||||
}
|
||||
|
@ -456,7 +454,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InvalidDataException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInvalidDataException<T>(string message)
|
||||
public static T ThrowInvalidDataException<T>(string? message)
|
||||
{
|
||||
throw new InvalidDataException(message);
|
||||
}
|
||||
|
@ -470,7 +468,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InvalidDataException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInvalidDataException<T>(string message, Exception innerException)
|
||||
public static T ThrowInvalidDataException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InvalidDataException(message, innerException);
|
||||
}
|
||||
|
@ -495,7 +493,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InvalidOperationException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInvalidOperationException<T>(string message)
|
||||
public static T ThrowInvalidOperationException<T>(string? message)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
@ -509,7 +507,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="InvalidOperationException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowInvalidOperationException<T>(string message, Exception innerException)
|
||||
public static T ThrowInvalidOperationException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InvalidOperationException(message, innerException);
|
||||
}
|
||||
|
@ -534,7 +532,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="LockRecursionException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowLockRecursionException<T>(string message)
|
||||
public static T ThrowLockRecursionException<T>(string? message)
|
||||
{
|
||||
throw new LockRecursionException(message);
|
||||
}
|
||||
|
@ -548,7 +546,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="LockRecursionException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowLockRecursionException<T>(string message, Exception innerException)
|
||||
public static T ThrowLockRecursionException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new LockRecursionException(message, innerException);
|
||||
}
|
||||
|
@ -573,7 +571,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingFieldException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingFieldException<T>(string message)
|
||||
public static T ThrowMissingFieldException<T>(string? message)
|
||||
{
|
||||
throw new MissingFieldException(message);
|
||||
}
|
||||
|
@ -587,7 +585,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingFieldException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingFieldException<T>(string message, Exception innerException)
|
||||
public static T ThrowMissingFieldException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingFieldException(message, innerException);
|
||||
}
|
||||
|
@ -602,7 +600,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingFieldException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingFieldException<T>(string className, string fieldName)
|
||||
public static T ThrowMissingFieldException<T>(string? className, string? fieldName)
|
||||
{
|
||||
throw new MissingFieldException(className, fieldName);
|
||||
}
|
||||
|
@ -628,7 +626,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMemberException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMemberException<T>(string message)
|
||||
public static T ThrowMissingMemberException<T>(string? message)
|
||||
{
|
||||
throw new MissingMemberException(message);
|
||||
}
|
||||
|
@ -642,7 +640,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMemberException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMemberException<T>(string message, Exception innerException)
|
||||
public static T ThrowMissingMemberException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingMemberException(message, innerException);
|
||||
}
|
||||
|
@ -657,7 +655,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMemberException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMemberException<T>(string className, string memberName)
|
||||
public static T ThrowMissingMemberException<T>(string? className, string? memberName)
|
||||
{
|
||||
throw new MissingMemberException(className, memberName);
|
||||
}
|
||||
|
@ -683,7 +681,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMethodException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMethodException<T>(string message)
|
||||
public static T ThrowMissingMethodException<T>(string? message)
|
||||
{
|
||||
throw new MissingMethodException(message);
|
||||
}
|
||||
|
@ -697,7 +695,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMethodException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMethodException<T>(string message, Exception innerException)
|
||||
public static T ThrowMissingMethodException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingMethodException(message, innerException);
|
||||
}
|
||||
|
@ -712,7 +710,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="MissingMethodException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowMissingMethodException<T>(string className, string methodName)
|
||||
public static T ThrowMissingMethodException<T>(string? className, string? methodName)
|
||||
{
|
||||
throw new MissingMethodException(className, methodName);
|
||||
}
|
||||
|
@ -738,7 +736,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="NotSupportedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowNotSupportedException<T>(string message)
|
||||
public static T ThrowNotSupportedException<T>(string? message)
|
||||
{
|
||||
throw new NotSupportedException(message);
|
||||
}
|
||||
|
@ -752,7 +750,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="NotSupportedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowNotSupportedException<T>(string message, Exception innerException)
|
||||
public static T ThrowNotSupportedException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new NotSupportedException(message, innerException);
|
||||
}
|
||||
|
@ -765,7 +763,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowObjectDisposedException<T>(string objectName)
|
||||
public static T ThrowObjectDisposedException<T>(string? objectName)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName);
|
||||
}
|
||||
|
@ -779,7 +777,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowObjectDisposedException<T>(string objectName, Exception innerException)
|
||||
public static T ThrowObjectDisposedException<T>(string? objectName, Exception? innerException)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName, innerException);
|
||||
}
|
||||
|
@ -793,7 +791,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowObjectDisposedException<T>(string objectName, string message)
|
||||
public static T ThrowObjectDisposedException<T>(string? objectName, string? message)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName, message);
|
||||
}
|
||||
|
@ -818,7 +816,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="OperationCanceledException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowOperationCanceledException<T>(string message)
|
||||
public static T ThrowOperationCanceledException<T>(string? message)
|
||||
{
|
||||
throw new OperationCanceledException(message);
|
||||
}
|
||||
|
@ -832,7 +830,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="OperationCanceledException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowOperationCanceledException<T>(string message, Exception innerException)
|
||||
public static T ThrowOperationCanceledException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new OperationCanceledException(message, innerException);
|
||||
}
|
||||
|
@ -859,7 +857,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="OperationCanceledException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowOperationCanceledException<T>(string message, CancellationToken token)
|
||||
public static T ThrowOperationCanceledException<T>(string? message, CancellationToken token)
|
||||
{
|
||||
throw new OperationCanceledException(message, token);
|
||||
}
|
||||
|
@ -874,7 +872,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="OperationCanceledException">Thrown with the specified parameters.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowOperationCanceledException<T>(string message, Exception innerException, CancellationToken token)
|
||||
public static T ThrowOperationCanceledException<T>(string? message, Exception? innerException, CancellationToken token)
|
||||
{
|
||||
throw new OperationCanceledException(message, innerException, token);
|
||||
}
|
||||
|
@ -899,7 +897,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="PlatformNotSupportedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowPlatformNotSupportedException<T>(string message)
|
||||
public static T ThrowPlatformNotSupportedException<T>(string? message)
|
||||
{
|
||||
throw new PlatformNotSupportedException(message);
|
||||
}
|
||||
|
@ -913,7 +911,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="PlatformNotSupportedException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowPlatformNotSupportedException<T>(string message, Exception innerException)
|
||||
public static T ThrowPlatformNotSupportedException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new PlatformNotSupportedException(message, innerException);
|
||||
}
|
||||
|
@ -938,7 +936,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="SynchronizationLockException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowSynchronizationLockException<T>(string message)
|
||||
public static T ThrowSynchronizationLockException<T>(string? message)
|
||||
{
|
||||
throw new SynchronizationLockException(message);
|
||||
}
|
||||
|
@ -952,7 +950,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="SynchronizationLockException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowSynchronizationLockException<T>(string message, Exception innerException)
|
||||
public static T ThrowSynchronizationLockException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new SynchronizationLockException(message, innerException);
|
||||
}
|
||||
|
@ -977,7 +975,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="TimeoutException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowTimeoutException<T>(string message)
|
||||
public static T ThrowTimeoutException<T>(string? message)
|
||||
{
|
||||
throw new TimeoutException(message);
|
||||
}
|
||||
|
@ -991,7 +989,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="TimeoutException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowTimeoutException<T>(string message, Exception innerException)
|
||||
public static T ThrowTimeoutException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new TimeoutException(message, innerException);
|
||||
}
|
||||
|
@ -1016,7 +1014,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="UnauthorizedAccessException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowUnauthorizedAccessException<T>(string message)
|
||||
public static T ThrowUnauthorizedAccessException<T>(string? message)
|
||||
{
|
||||
throw new UnauthorizedAccessException(message);
|
||||
}
|
||||
|
@ -1030,7 +1028,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="UnauthorizedAccessException">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowUnauthorizedAccessException<T>(string message, Exception innerException)
|
||||
public static T ThrowUnauthorizedAccessException<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new UnauthorizedAccessException(message, innerException);
|
||||
}
|
||||
|
@ -1069,7 +1067,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowWin32Exception<T>(int error, string message)
|
||||
public static T ThrowWin32Exception<T>(int error, string? message)
|
||||
{
|
||||
throw new Win32Exception(error, message);
|
||||
}
|
||||
|
@ -1082,7 +1080,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowWin32Exception<T>(string message)
|
||||
public static T ThrowWin32Exception<T>(string? message)
|
||||
{
|
||||
throw new Win32Exception(message);
|
||||
}
|
||||
|
@ -1096,7 +1094,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
/// <returns>This method always throws, so it actually never returns a value.</returns>
|
||||
[DoesNotReturn]
|
||||
public static T ThrowWin32Exception<T>(string message, Exception innerException)
|
||||
public static T ThrowWin32Exception<T>(string? message, Exception? innerException)
|
||||
{
|
||||
throw new Win32Exception(message, innerException);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ using System.Runtime.InteropServices;
|
|||
#endif
|
||||
using System.Threading;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -36,7 +34,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArrayTypeMismatchException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArrayTypeMismatchException(string message)
|
||||
public static void ThrowArrayTypeMismatchException(string? message)
|
||||
{
|
||||
throw new ArrayTypeMismatchException(message);
|
||||
}
|
||||
|
@ -48,7 +46,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ArrayTypeMismatchException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArrayTypeMismatchException(string message, Exception innerException)
|
||||
public static void ThrowArrayTypeMismatchException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArrayTypeMismatchException(message, innerException);
|
||||
}
|
||||
|
@ -69,7 +67,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArgumentException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentException(string message)
|
||||
public static void ThrowArgumentException(string? message)
|
||||
{
|
||||
throw new ArgumentException(message);
|
||||
}
|
||||
|
@ -81,7 +79,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentException(string message, Exception innerException)
|
||||
public static void ThrowArgumentException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentException(message, innerException);
|
||||
}
|
||||
|
@ -93,7 +91,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentException(string name, string message)
|
||||
public static void ThrowArgumentException(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentException(message, name);
|
||||
}
|
||||
|
@ -106,7 +104,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ArgumentException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentException(string name, string message, Exception innerException)
|
||||
public static void ThrowArgumentException(string? name, string? message, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentException(message, name, innerException);
|
||||
}
|
||||
|
@ -127,7 +125,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="name">The argument name.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentNullException(string name)
|
||||
public static void ThrowArgumentNullException(string? name)
|
||||
{
|
||||
throw new ArgumentNullException(name);
|
||||
}
|
||||
|
@ -139,7 +137,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentNullException(string name, Exception innerException)
|
||||
public static void ThrowArgumentNullException(string? name, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentNullException(name, innerException);
|
||||
}
|
||||
|
@ -151,7 +149,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentNullException(string name, string message)
|
||||
public static void ThrowArgumentNullException(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentNullException(name, message);
|
||||
}
|
||||
|
@ -172,7 +170,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="name">The argument name.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentOutOfRangeException(string name)
|
||||
public static void ThrowArgumentOutOfRangeException(string? name)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name);
|
||||
}
|
||||
|
@ -184,7 +182,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentOutOfRangeException(string name, Exception innerException)
|
||||
public static void ThrowArgumentOutOfRangeException(string? name, Exception? innerException)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, innerException);
|
||||
}
|
||||
|
@ -196,7 +194,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentOutOfRangeException(string name, string message)
|
||||
public static void ThrowArgumentOutOfRangeException(string? name, string? message)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, message);
|
||||
}
|
||||
|
@ -209,7 +207,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowArgumentOutOfRangeException(string name, object value, string message)
|
||||
public static void ThrowArgumentOutOfRangeException(string? name, object? value, string? message)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(name, value, message);
|
||||
}
|
||||
|
@ -231,7 +229,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="COMException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowCOMException(string message)
|
||||
public static void ThrowCOMException(string? message)
|
||||
{
|
||||
throw new COMException(message);
|
||||
}
|
||||
|
@ -243,7 +241,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="COMException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowCOMException(string message, Exception innerException)
|
||||
public static void ThrowCOMException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new COMException(message, innerException);
|
||||
}
|
||||
|
@ -255,7 +253,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="error">The HRESULT of the errror to include.</param>
|
||||
/// <exception cref="COMException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowCOMException(string message, int error)
|
||||
public static void ThrowCOMException(string? message, int error)
|
||||
{
|
||||
throw new COMException(message, error);
|
||||
}
|
||||
|
@ -276,7 +274,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ExternalException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowExternalException(string message)
|
||||
public static void ThrowExternalException(string? message)
|
||||
{
|
||||
throw new ExternalException(message);
|
||||
}
|
||||
|
@ -288,7 +286,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ExternalException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowExternalException(string message, Exception innerException)
|
||||
public static void ThrowExternalException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new ExternalException(message, innerException);
|
||||
}
|
||||
|
@ -300,7 +298,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="error">The HRESULT of the errror to include.</param>
|
||||
/// <exception cref="ExternalException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowExternalException(string message, int error)
|
||||
public static void ThrowExternalException(string? message, int error)
|
||||
{
|
||||
throw new ExternalException(message, error);
|
||||
}
|
||||
|
@ -322,7 +320,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="FormatException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowFormatException(string message)
|
||||
public static void ThrowFormatException(string? message)
|
||||
{
|
||||
throw new FormatException(message);
|
||||
}
|
||||
|
@ -334,7 +332,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="FormatException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowFormatException(string message, Exception innerException)
|
||||
public static void ThrowFormatException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new FormatException(message, innerException);
|
||||
}
|
||||
|
@ -356,7 +354,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="InsufficientMemoryException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInsufficientMemoryException(string message)
|
||||
public static void ThrowInsufficientMemoryException(string? message)
|
||||
{
|
||||
throw new InsufficientMemoryException(message);
|
||||
}
|
||||
|
@ -368,7 +366,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="InsufficientMemoryException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInsufficientMemoryException(string message, Exception innerException)
|
||||
public static void ThrowInsufficientMemoryException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InsufficientMemoryException(message, innerException);
|
||||
}
|
||||
|
@ -390,7 +388,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="InvalidDataException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInvalidDataException(string message)
|
||||
public static void ThrowInvalidDataException(string? message)
|
||||
{
|
||||
throw new InvalidDataException(message);
|
||||
}
|
||||
|
@ -402,7 +400,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="InvalidDataException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInvalidDataException(string message, Exception innerException)
|
||||
public static void ThrowInvalidDataException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InvalidDataException(message, innerException);
|
||||
}
|
||||
|
@ -423,7 +421,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInvalidOperationException(string message)
|
||||
public static void ThrowInvalidOperationException(string? message)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
@ -435,7 +433,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowInvalidOperationException(string message, Exception innerException)
|
||||
public static void ThrowInvalidOperationException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new InvalidOperationException(message, innerException);
|
||||
}
|
||||
|
@ -456,7 +454,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="LockRecursionException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowLockRecursionException(string message)
|
||||
public static void ThrowLockRecursionException(string? message)
|
||||
{
|
||||
throw new LockRecursionException(message);
|
||||
}
|
||||
|
@ -468,7 +466,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="LockRecursionException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowLockRecursionException(string message, Exception innerException)
|
||||
public static void ThrowLockRecursionException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new LockRecursionException(message, innerException);
|
||||
}
|
||||
|
@ -489,7 +487,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="MissingFieldException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingFieldException(string message)
|
||||
public static void ThrowMissingFieldException(string? message)
|
||||
{
|
||||
throw new MissingFieldException(message);
|
||||
}
|
||||
|
@ -501,7 +499,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="MissingFieldException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingFieldException(string message, Exception innerException)
|
||||
public static void ThrowMissingFieldException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingFieldException(message, innerException);
|
||||
}
|
||||
|
@ -514,7 +512,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="fieldName">The target field being retrieved.</param>
|
||||
/// <exception cref="MissingFieldException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingFieldException(string className, string fieldName)
|
||||
public static void ThrowMissingFieldException(string? className, string? fieldName)
|
||||
{
|
||||
throw new MissingFieldException(className, fieldName);
|
||||
}
|
||||
|
@ -536,7 +534,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="MissingMemberException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMemberException(string message)
|
||||
public static void ThrowMissingMemberException(string? message)
|
||||
{
|
||||
throw new MissingMemberException(message);
|
||||
}
|
||||
|
@ -548,7 +546,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="MissingMemberException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMemberException(string message, Exception innerException)
|
||||
public static void ThrowMissingMemberException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingMemberException(message, innerException);
|
||||
}
|
||||
|
@ -561,7 +559,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="memberName">The target member being retrieved.</param>
|
||||
/// <exception cref="MissingMemberException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMemberException(string className, string memberName)
|
||||
public static void ThrowMissingMemberException(string? className, string? memberName)
|
||||
{
|
||||
throw new MissingMemberException(className, memberName);
|
||||
}
|
||||
|
@ -583,7 +581,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="MissingMethodException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMethodException(string message)
|
||||
public static void ThrowMissingMethodException(string? message)
|
||||
{
|
||||
throw new MissingMethodException(message);
|
||||
}
|
||||
|
@ -595,7 +593,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="MissingMethodException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMethodException(string message, Exception innerException)
|
||||
public static void ThrowMissingMethodException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new MissingMethodException(message, innerException);
|
||||
}
|
||||
|
@ -608,7 +606,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="methodName">The target method being retrieved.</param>
|
||||
/// <exception cref="MissingMethodException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowMissingMethodException(string className, string methodName)
|
||||
public static void ThrowMissingMethodException(string? className, string? methodName)
|
||||
{
|
||||
throw new MissingMethodException(className, methodName);
|
||||
}
|
||||
|
@ -630,7 +628,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="NotSupportedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowNotSupportedException(string message)
|
||||
public static void ThrowNotSupportedException(string? message)
|
||||
{
|
||||
throw new NotSupportedException(message);
|
||||
}
|
||||
|
@ -642,7 +640,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="NotSupportedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowNotSupportedException(string message, Exception innerException)
|
||||
public static void ThrowNotSupportedException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new NotSupportedException(message, innerException);
|
||||
}
|
||||
|
@ -653,7 +651,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="objectName">The name of the disposed object.</param>
|
||||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowObjectDisposedException(string objectName)
|
||||
public static void ThrowObjectDisposedException(string? objectName)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName);
|
||||
}
|
||||
|
@ -665,7 +663,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowObjectDisposedException(string objectName, Exception innerException)
|
||||
public static void ThrowObjectDisposedException(string? objectName, Exception? innerException)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName, innerException);
|
||||
}
|
||||
|
@ -677,7 +675,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="ObjectDisposedException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowObjectDisposedException(string objectName, string message)
|
||||
public static void ThrowObjectDisposedException(string? objectName, string? message)
|
||||
{
|
||||
throw new ObjectDisposedException(objectName, message);
|
||||
}
|
||||
|
@ -698,7 +696,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="OperationCanceledException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowOperationCanceledException(string message)
|
||||
public static void ThrowOperationCanceledException(string? message)
|
||||
{
|
||||
throw new OperationCanceledException(message);
|
||||
}
|
||||
|
@ -710,7 +708,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="OperationCanceledException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowOperationCanceledException(string message, Exception innerException)
|
||||
public static void ThrowOperationCanceledException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new OperationCanceledException(message, innerException);
|
||||
}
|
||||
|
@ -733,7 +731,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="token">The <see cref="CancellationToken"/> in use.</param>
|
||||
/// <exception cref="OperationCanceledException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowOperationCanceledException(string message, CancellationToken token)
|
||||
public static void ThrowOperationCanceledException(string? message, CancellationToken token)
|
||||
{
|
||||
throw new OperationCanceledException(message, token);
|
||||
}
|
||||
|
@ -746,7 +744,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="token">The <see cref="CancellationToken"/> in use.</param>
|
||||
/// <exception cref="OperationCanceledException">Thrown with the specified parameters.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowOperationCanceledException(string message, Exception innerException, CancellationToken token)
|
||||
public static void ThrowOperationCanceledException(string? message, Exception? innerException, CancellationToken token)
|
||||
{
|
||||
throw new OperationCanceledException(message, innerException, token);
|
||||
}
|
||||
|
@ -767,7 +765,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="PlatformNotSupportedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowPlatformNotSupportedException(string message)
|
||||
public static void ThrowPlatformNotSupportedException(string? message)
|
||||
{
|
||||
throw new PlatformNotSupportedException(message);
|
||||
}
|
||||
|
@ -779,7 +777,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="PlatformNotSupportedException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowPlatformNotSupportedException(string message, Exception innerException)
|
||||
public static void ThrowPlatformNotSupportedException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new PlatformNotSupportedException(message, innerException);
|
||||
}
|
||||
|
@ -800,7 +798,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="SynchronizationLockException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowSynchronizationLockException(string message)
|
||||
public static void ThrowSynchronizationLockException(string? message)
|
||||
{
|
||||
throw new SynchronizationLockException(message);
|
||||
}
|
||||
|
@ -812,7 +810,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="SynchronizationLockException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowSynchronizationLockException(string message, Exception innerException)
|
||||
public static void ThrowSynchronizationLockException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new SynchronizationLockException(message, innerException);
|
||||
}
|
||||
|
@ -833,7 +831,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="TimeoutException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowTimeoutException(string message)
|
||||
public static void ThrowTimeoutException(string? message)
|
||||
{
|
||||
throw new TimeoutException(message);
|
||||
}
|
||||
|
@ -845,7 +843,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="TimeoutException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowTimeoutException(string message, Exception innerException)
|
||||
public static void ThrowTimeoutException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new TimeoutException(message, innerException);
|
||||
}
|
||||
|
@ -866,7 +864,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="UnauthorizedAccessException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowUnauthorizedAccessException(string message)
|
||||
public static void ThrowUnauthorizedAccessException(string? message)
|
||||
{
|
||||
throw new UnauthorizedAccessException(message);
|
||||
}
|
||||
|
@ -878,7 +876,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="UnauthorizedAccessException">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowUnauthorizedAccessException(string message, Exception innerException)
|
||||
public static void ThrowUnauthorizedAccessException(string? message, Exception? innerException)
|
||||
{
|
||||
throw new UnauthorizedAccessException(message, innerException);
|
||||
}
|
||||
|
@ -911,7 +909,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowWin32Exception(int error, string message)
|
||||
public static void ThrowWin32Exception(int error, string? message)
|
||||
{
|
||||
throw new Win32Exception(error, message);
|
||||
}
|
||||
|
@ -922,7 +920,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="message">The message to include in the exception.</param>
|
||||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowWin32Exception(string message)
|
||||
public static void ThrowWin32Exception(string? message)
|
||||
{
|
||||
throw new Win32Exception(message);
|
||||
}
|
||||
|
@ -934,7 +932,7 @@ namespace Microsoft.Toolkit.Diagnostics
|
|||
/// <param name="innerException">The inner <see cref="Exception"/> to include.</param>
|
||||
/// <exception cref="Win32Exception">Thrown with the specified parameter.</exception>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowWin32Exception(string message, Exception innerException)
|
||||
public static void ThrowWin32Exception(string? message, Exception? innerException)
|
||||
{
|
||||
throw new Win32Exception(message, innerException);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <param name="rectarray">The source array.</param>
|
||||
/// <param name="column">Column record to retrieve, 0-based index.</param>
|
||||
/// <returns>Yielded enumerable of column elements for given column, and default values for smaller inner arrays.</returns>
|
||||
public static IEnumerable<T> GetColumn<T>(this T[][] rectarray, int column)
|
||||
public static IEnumerable<T?> GetColumn<T>(this T?[][] rectarray, int column)
|
||||
{
|
||||
if (column < 0 || column >= rectarray.Max(array => array.Length))
|
||||
{
|
||||
|
@ -49,10 +49,10 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <typeparam name="T">The element type of the array.</typeparam>
|
||||
/// <param name="array">The source array.</param>
|
||||
/// <returns>The <see cref="string"/> representation of the array.</returns>
|
||||
public static string ToArrayString<T>(this T[] array)
|
||||
public static string ToArrayString<T>(this T?[] array)
|
||||
{
|
||||
// The returned string will be in the following format:
|
||||
// [1, 2, 3]
|
||||
// [1, 2, 3]
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.Append('[');
|
||||
|
@ -64,7 +64,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
builder.Append(",\t");
|
||||
}
|
||||
|
||||
builder.Append(array[i].ToString());
|
||||
builder.Append(array[i]?.ToString());
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
|
@ -78,7 +78,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <typeparam name="T">The element type of the array.</typeparam>
|
||||
/// <param name="mdarray">The source array.</param>
|
||||
/// <returns>String representation of the array.</returns>
|
||||
public static string ToArrayString<T>(this T[][] mdarray)
|
||||
public static string ToArrayString<T>(this T?[][] mdarray)
|
||||
{
|
||||
// The returned string uses the same format as the overload for 2D arrays
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -96,7 +96,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
|
||||
builder.Append('[');
|
||||
|
||||
T[] row = mdarray[i];
|
||||
T?[] row = mdarray[i];
|
||||
|
||||
for (int j = 0; j < row.Length; j++)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
builder.Append(",\t");
|
||||
}
|
||||
|
||||
builder.Append(row[j].ToString());
|
||||
builder.Append(row[j]?.ToString());
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
|
@ -122,7 +122,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <typeparam name="T">The element type of the array.</typeparam>
|
||||
/// <param name="array">The source array.</param>
|
||||
/// <returns>The <see cref="string"/> representation of the array.</returns>
|
||||
public static string ToArrayString<T>(this T[,] array)
|
||||
public static string ToArrayString<T>(this T?[,] array)
|
||||
{
|
||||
// The returned string will be in the following format:
|
||||
// [[1, 2, 3],
|
||||
|
@ -154,7 +154,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
builder.Append(",\t");
|
||||
}
|
||||
|
||||
builder.Append(array[i, j].ToString());
|
||||
builder.Append(array[i, j]?.ToString());
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
|
|
|
@ -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 System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
@ -62,15 +62,20 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// </summary>
|
||||
/// <param name="str">The string to test.</param>
|
||||
/// <returns><c>true</c> for a valid decimal number; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsDecimal(this string str)
|
||||
=> decimal.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out _);
|
||||
public static bool IsDecimal([NotNullWhen(true)] this string? str)
|
||||
{
|
||||
return decimal.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a string is a valid integer.
|
||||
/// </summary>
|
||||
/// <param name="str">The string to test.</param>
|
||||
/// <returns><c>true</c> for a valid integer; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsNumeric(this string str) => int.TryParse(str, out _);
|
||||
public static bool IsNumeric([NotNullWhen(true)] this string? str)
|
||||
{
|
||||
return int.TryParse(str, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a string is a valid phone number.
|
||||
|
@ -91,9 +96,10 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// </summary>
|
||||
/// <param name="htmlText">HTML string.</param>
|
||||
/// <returns>Decoded HTML string.</returns>
|
||||
public static string DecodeHtml(this string htmlText)
|
||||
[return: NotNullIfNotNull("htmlText")]
|
||||
public static string? DecodeHtml(this string? htmlText)
|
||||
{
|
||||
if (htmlText == null)
|
||||
if (htmlText is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -131,7 +137,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <param name="value">The string to be truncated.</param>
|
||||
/// <param name="length">The maximum length.</param>
|
||||
/// <returns>Truncated string.</returns>
|
||||
public static string Truncate(this string value, int length) => Truncate(value, length, false);
|
||||
public static string Truncate(this string? value, int length) => Truncate(value, length, false);
|
||||
|
||||
/// <summary>
|
||||
/// Provide better linking for resourced strings.
|
||||
|
@ -148,11 +154,12 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <param name="length">The maximum length.</param>
|
||||
/// <param name="ellipsis"><c>true</c> to add ellipsis to the truncated text; otherwise, <c>false</c>.</param>
|
||||
/// <returns>Truncated string.</returns>
|
||||
public static string Truncate(this string value, int length, bool ellipsis)
|
||||
public static string Truncate(this string? value, int length, bool ellipsis)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
value = value.Trim();
|
||||
value = value!.Trim();
|
||||
|
||||
if (value.Length > length)
|
||||
{
|
||||
if (ellipsis)
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -69,8 +66,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// <remarks>This method does not block if <paramref name="task"/> has not completed yet.</remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[return: MaybeNull]
|
||||
public static T GetResultOrDefault<T>(this Task<T> task)
|
||||
public static T? GetResultOrDefault<T>(this Task<T?> task)
|
||||
{
|
||||
#if NETSTANDARD2_1
|
||||
return task.IsCompletedSuccessfully ? task.Result : default;
|
||||
|
|
|
@ -11,8 +11,6 @@ using System.Reflection;
|
|||
#endif
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.Toolkit.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
public static class ValueTypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the table of hex characters (doesn't allocate, maps to .text section, see <see href="https://github.com/dotnet/roslyn/pull/24621"/>)
|
||||
/// Gets the table of hex characters (doesn't allocate, maps to .text section, see <see href="https://github.com/dotnet/roslyn/pull/24621"/>).
|
||||
/// </summary>
|
||||
private static ReadOnlySpan<byte> HexCharactersTable => new[]
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ namespace Microsoft.Toolkit.Extensions
|
|||
/// </code>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[SkipLocalsInit]
|
||||
public static unsafe string ToHexString<T>(this T value)
|
||||
where T : unmanaged
|
||||
{
|
||||
|
@ -55,12 +55,11 @@ namespace Microsoft.Toolkit.Extensions
|
|||
p[0] = '0';
|
||||
p[1] = 'x';
|
||||
|
||||
ref byte r0 = ref Unsafe.As<T, byte>(ref value);
|
||||
ref byte rh = ref MemoryMarshal.GetReference(HexCharactersTable);
|
||||
|
||||
for (int i = 0, j = bufferSize - 2; i < sizeOfT; i++, j -= 2)
|
||||
{
|
||||
byte b = Unsafe.Add(ref r0, i);
|
||||
byte b = ((byte*)&value)[i];
|
||||
int
|
||||
low = b & 0x0F,
|
||||
high = (b & 0xF0) >> 4;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard1.4;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TargetFrameworks>netstandard1.4;netstandard2.0;netstandard2.1;net5.0</TargetFrameworks>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Nullable>enable</Nullable>
|
||||
<Title>Windows Community Toolkit .NET Standard</Title>
|
||||
<Description>
|
||||
This package includes .NET Standard code only helpers such as:
|
||||
|
@ -12,23 +13,39 @@
|
|||
</Description>
|
||||
<PackageTags>UWP Toolkit Windows IncrementalLoadingCollection String Array extensions helpers</PackageTags>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition=" '$(TargetFramework)' == 'netstandard1.4' ">
|
||||
<ItemGroup>
|
||||
|
||||
<!-- .NET Standard 1.4 doesn't have the Span<T> type, ValueTuple or the [Pure] attribute -->
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.4' ">
|
||||
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
<!-- .NET Standard 1.4 doesn't have the Span<T> type, ValueTuple or the [Pure] attribute -->
|
||||
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<ItemGroup>
|
||||
|
||||
<!-- .NET Standard 2.0 doesn't have the Span<T> type -->
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
<!-- .NET Standard 2.0 doesn't have the Span<T> type -->
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<PropertyGroup>
|
||||
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
<!-- .NET Standard 2.1 doesn't have the Unsafe type -->
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
<!-- .NET Standard 2.1 doesn't have the Unsafe type -->
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition=" '$(TargetFramework)' == 'net5.0' ">
|
||||
<PropertyGroup>
|
||||
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Diagnostics\Generated\Guard.Comparable.Numeric.tt">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<IsPackable>false</IsPackable>
|
||||
|
|
|
@ -188,28 +188,43 @@ namespace UnitTests.HighPerformance.Buffers
|
|||
[TestMethod]
|
||||
public void Test_ArrayPoolBufferWriterOfT_AsStream()
|
||||
{
|
||||
const int GuidSize = 16;
|
||||
|
||||
var writer = new ArrayPoolBufferWriter<byte>();
|
||||
var guid = Guid.NewGuid();
|
||||
|
||||
Span<byte> data = Guid.NewGuid().ToByteArray();
|
||||
// Here we first get a stream with the extension targeting ArrayPoolBufferWriter<T>.
|
||||
// This will wrap it into a custom internal stream type and produce a write-only
|
||||
// stream that essentially mirrors the IBufferWriter<T> functionality as a stream.
|
||||
using (Stream writeStream = writer.AsStream())
|
||||
{
|
||||
writeStream.Write(guid);
|
||||
}
|
||||
|
||||
data.CopyTo(writer.GetSpan(data.Length));
|
||||
Assert.AreEqual(writer.WrittenCount, GuidSize);
|
||||
|
||||
writer.Advance(data.Length);
|
||||
// Here we get a readable stream instead, and read from it to ensure
|
||||
// the previous data was written correctly from the writeable stream.
|
||||
using (Stream stream = writer.WrittenMemory.AsStream())
|
||||
{
|
||||
Assert.AreEqual(stream.Length, GuidSize);
|
||||
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
byte[] result = new byte[GuidSize];
|
||||
|
||||
Stream stream = writer.AsStream();
|
||||
stream.Read(result, 0, result.Length);
|
||||
|
||||
Assert.AreEqual(stream.Length, data.Length);
|
||||
// Read the guid data and ensure it matches our initial guid
|
||||
Assert.IsTrue(new Guid(result).Equals(guid));
|
||||
}
|
||||
|
||||
byte[] result = new byte[16];
|
||||
// Do a dummy write just to ensure the writer isn't disposed here.
|
||||
// This is because we got a stream from a memory, not a memory owner.
|
||||
writer.Write((byte)42);
|
||||
writer.Advance(1);
|
||||
|
||||
stream.Read(result, 0, result.Length);
|
||||
|
||||
Assert.IsTrue(data.SequenceEqual(result));
|
||||
|
||||
stream.Dispose();
|
||||
writer.Dispose();
|
||||
|
||||
// Now check that the writer is actually disposed instead
|
||||
Assert.ThrowsException<ObjectDisposedException>(() => writer.Capacity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -436,7 +436,7 @@ namespace UnitTests.HighPerformance.Extensions
|
|||
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.GetColumn(0).ToArray());
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
[TestCategory("ArrayExtensions")]
|
||||
[TestMethod]
|
||||
public void Test_ArrayExtensions_2D_AsSpan_Empty()
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace UnitTests.HighPerformance.Helpers
|
|||
TestForType<char>();
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
[TestCategory("HashCodeOfT")]
|
||||
[TestMethod]
|
||||
public void Test_HashCodeOfT_ManagedType_TestRepeat()
|
||||
|
@ -88,6 +89,7 @@ namespace UnitTests.HighPerformance.Helpers
|
|||
Assert.AreEqual(hash1, hash2, $"Failed {typeof(string)} test with count {count}: got {hash1} and then {hash2}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Performs a test for a specified type.
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace UnitTests.HighPerformance.Helpers
|
|||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
[TestCategory("ParallelHelper")]
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace UnitTests.HighPerformance.Helpers
|
|||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
[TestCategory("ParallelHelper")]
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
// 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.Buffers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.HighPerformance.Buffers;
|
||||
using Microsoft.Toolkit.HighPerformance.Extensions;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace UnitTests.HighPerformance.Streams
|
||||
{
|
||||
[TestClass]
|
||||
public class Test_IBufferWriterStream
|
||||
{
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
public void Test_IBufferWriterStream_Lifecycle()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
|
||||
// Get a stream from a buffer writer aand validate that it can only be written to.
|
||||
// This is to mirror the same functionality as the IBufferWriter<T> interface.
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
Assert.IsFalse(stream.CanRead);
|
||||
Assert.IsFalse(stream.CanSeek);
|
||||
Assert.IsTrue(stream.CanWrite);
|
||||
|
||||
Assert.ThrowsException<NotSupportedException>(() => stream.Length);
|
||||
Assert.ThrowsException<NotSupportedException>(() => stream.Position);
|
||||
|
||||
// Dispose the stream and check that no operation is now allowed
|
||||
stream.Dispose();
|
||||
|
||||
Assert.IsFalse(stream.CanRead);
|
||||
Assert.IsFalse(stream.CanSeek);
|
||||
Assert.IsFalse(stream.CanWrite);
|
||||
Assert.ThrowsException<NotSupportedException>(() => stream.Length);
|
||||
Assert.ThrowsException<NotSupportedException>(() => stream.Position);
|
||||
}
|
||||
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
public void Test_IBufferWriterStream_Write_Array()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
byte[] data = Test_MemoryStream.CreateRandomData(64);
|
||||
|
||||
// Write random data to the stream wrapping the buffer writer, and validate
|
||||
// that the state of the writer is consistent, and the written content matches.
|
||||
stream.Write(data, 0, data.Length);
|
||||
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
Assert.IsTrue(writer.WrittenSpan.SequenceEqual(data));
|
||||
|
||||
// A few tests with invalid inputs (null buffers, invalid indices, etc.)
|
||||
Assert.ThrowsException<ArgumentNullException>(() => stream.Write(null, 0, 10));
|
||||
Assert.ThrowsException<ArgumentOutOfRangeException>(() => stream.Write(data, -1, 10));
|
||||
Assert.ThrowsException<ArgumentException>(() => stream.Write(data, 200, 10));
|
||||
Assert.ThrowsException<ArgumentOutOfRangeException>(() => stream.Write(data, 0, -24));
|
||||
Assert.ThrowsException<ArgumentException>(() => stream.Write(data, 0, 200));
|
||||
|
||||
stream.Dispose();
|
||||
|
||||
Assert.ThrowsException<ObjectDisposedException>(() => stream.Write(data, 0, data.Length));
|
||||
}
|
||||
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
public async Task Test_IBufferWriterStream_WriteAsync_Array()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
byte[] data = Test_MemoryStream.CreateRandomData(64);
|
||||
|
||||
// Same test as above, but using an asynchronous write instead
|
||||
await stream.WriteAsync(data, 0, data.Length);
|
||||
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
Assert.IsTrue(writer.WrittenSpan.SequenceEqual(data));
|
||||
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => stream.WriteAsync(null, 0, 10));
|
||||
await Assert.ThrowsExceptionAsync<ArgumentOutOfRangeException>(() => stream.WriteAsync(data, -1, 10));
|
||||
await Assert.ThrowsExceptionAsync<ArgumentException>(() => stream.WriteAsync(data, 200, 10));
|
||||
await Assert.ThrowsExceptionAsync<ArgumentOutOfRangeException>(() => stream.WriteAsync(data, 0, -24));
|
||||
await Assert.ThrowsExceptionAsync<ArgumentException>(() => stream.WriteAsync(data, 0, 200));
|
||||
|
||||
stream.Dispose();
|
||||
|
||||
await Assert.ThrowsExceptionAsync<ObjectDisposedException>(() => stream.WriteAsync(data, 0, data.Length));
|
||||
}
|
||||
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
[SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500", Justification = "Array initialization")]
|
||||
public void Test_IBufferWriterStream_WriteByte()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
ReadOnlySpan<byte> data = stackalloc byte[] { 1, 128, 255, 32 };
|
||||
|
||||
foreach (var item in data.Enumerate())
|
||||
{
|
||||
// Since we're enumerating, we can also double check the current written count
|
||||
// at each iteration, to ensure the writes are done correctly every time.
|
||||
Assert.AreEqual(writer.WrittenCount, item.Index);
|
||||
|
||||
// Write a number of bytes one by one to test this API as well
|
||||
stream.WriteByte(item.Value);
|
||||
}
|
||||
|
||||
// Validate the final written length and actual data
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
Assert.IsTrue(data.SequenceEqual(writer.WrittenSpan));
|
||||
|
||||
Assert.ThrowsException<NotSupportedException>(() => stream.ReadByte());
|
||||
}
|
||||
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
public void Test_IBufferWriterStream_Write_Span()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
Memory<byte> data = Test_MemoryStream.CreateRandomData(64);
|
||||
|
||||
// This will use the extension when on .NET Standard 2.0,
|
||||
// as the Stream class doesn't have Spam<T> or Memory<T>
|
||||
// public APIs there. This is the case eg. on UWP as well.
|
||||
stream.Write(data.Span);
|
||||
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
Assert.IsTrue(data.Span.SequenceEqual(writer.WrittenSpan));
|
||||
}
|
||||
|
||||
[TestCategory("IBufferWriterStream")]
|
||||
[TestMethod]
|
||||
public async Task Test_IBufferWriterStream_WriteAsync_Memory()
|
||||
{
|
||||
ArrayPoolBufferWriter<byte> writer = new ArrayPoolBufferWriter<byte>();
|
||||
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
||||
|
||||
Memory<byte> data = Test_MemoryStream.CreateRandomData(64);
|
||||
|
||||
// Same as the other asynchronous test above, but writing from a Memory<T>
|
||||
await stream.WriteAsync(data);
|
||||
|
||||
Assert.AreEqual(writer.WrittenCount, data.Length);
|
||||
Assert.IsTrue(data.Span.SequenceEqual(writer.WrittenSpan));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -272,7 +272,7 @@ namespace UnitTests.HighPerformance.Streams
|
|||
/// <param name="count">The number of array items to create.</param>
|
||||
/// <returns>The returned random array.</returns>
|
||||
[Pure]
|
||||
private static byte[] CreateRandomData(int count)
|
||||
internal static byte[] CreateRandomData(int count)
|
||||
{
|
||||
var random = new Random(DateTime.Now.Ticks.GetHashCode());
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
|
|
@ -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.
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
#if NETCOREAPP3_1 || NET5_0
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Memory\Test_Memory2D{T}.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Memory\Test_Span2D{T}.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Streams\Test_IMemoryOwnerStream.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Streams\Test_IBufferWriterStream.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Streams\Test_MemoryStream.ThrowExceptions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Streams\Test_MemoryStream.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Test_Box{T}.cs" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Uwp.Extensions;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
@ -21,7 +22,7 @@ namespace UnitTests.XamlIslands.UWPApp
|
|||
[TestInitialize]
|
||||
public async Task Init()
|
||||
{
|
||||
await App.Dispatcher.ExecuteOnUIThreadAsync(() =>
|
||||
await App.Dispatcher.EnqueueAsync(() =>
|
||||
{
|
||||
var xamlItemsPanelTemplate = @"<Grid xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
||||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
|
||||
|
@ -65,7 +66,7 @@ namespace UnitTests.XamlIslands.UWPApp
|
|||
[TestCleanup]
|
||||
public async Task Cleanup()
|
||||
{
|
||||
await App.Dispatcher.ExecuteOnUIThreadAsync(() =>
|
||||
await App.Dispatcher.EnqueueAsync(() =>
|
||||
{
|
||||
GazeInput.SetInteraction(_grid, Interaction.Disabled);
|
||||
});
|
||||
|
@ -76,7 +77,7 @@ namespace UnitTests.XamlIslands.UWPApp
|
|||
[Ignore]
|
||||
public async Task Gaze_DoesNotCrashOnIslands()
|
||||
{
|
||||
await App.Dispatcher.ExecuteOnUIThreadAsync(async () =>
|
||||
await App.Dispatcher.EnqueueAsync(async () =>
|
||||
{
|
||||
await Task.Delay(10000);
|
||||
|
||||
|
|
|
@ -43,11 +43,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Toolkit.Uwp.Notif
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests.Notifications.NetCore", "UnitTests\UnitTests.Notifications.NetCore\UnitTests.Notifications.NetCore.csproj", "{94994424-5F60-4CD8-ABA2-101779066208}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Notifications.WinRT", "UnitTests\UnitTests.Notifications.WinRT\UnitTests.Notifications.WinRT.csproj", "{EFA96B3C-857E-4659-B942-6BEF7719F4CA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{97EE849B-403C-490E-80ED-D19D7CC153FD} = {97EE849B-403C-490E-80ED-D19D7CC153FD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CFA75BE0-5A44-45DE-8114-426A605B062B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
|
@ -148,7 +143,6 @@ Global
|
|||
UnitTests\UnitTests.Shared\UnitTests.Shared.projitems*{a139968e-ad78-4e8c-93b8-9a5523bcac89}*SharedItemsImports = 4
|
||||
UnitTests\UnitTests.Notifications.Shared\UnitTests.Notifications.Shared.projitems*{bab1caf4-c400-4a7f-a987-c576de63cffd}*SharedItemsImports = 4
|
||||
UnitTests\UnitTests.HighPerformance.Shared\UnitTests.HighPerformance.Shared.projitems*{d9bdbc68-3d0a-47fc-9c88-0bf769101644}*SharedItemsImports = 5
|
||||
UnitTests\UnitTests.Notifications.Shared\UnitTests.Notifications.Shared.projitems*{efa96b3c-857e-4659-b942-6bef7719f4ca}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -486,34 +480,6 @@ Global
|
|||
{94994424-5F60-4CD8-ABA2-101779066208}.Release|x64.Build.0 = Release|Any CPU
|
||||
{94994424-5F60-4CD8-ABA2-101779066208}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{94994424-5F60-4CD8-ABA2-101779066208}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x64.Build.0 = Debug|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x86.Build.0 = Debug|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|Any CPU.Build.0 = Release|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM.Build.0 = Release|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x64.ActiveCfg = Release|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x64.Build.0 = Release|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x64.Deploy.0 = Release|x64
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x86.ActiveCfg = Release|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x86.Build.0 = Release|x86
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA}.Release|x86.Deploy.0 = Release|x86
|
||||
{7AEFC959-ED7C-4D96-9E92-72609B40FBE0}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{7AEFC959-ED7C-4D96-9E92-72609B40FBE0}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{7AEFC959-ED7C-4D96-9E92-72609B40FBE0}.Debug|ARM.ActiveCfg = Debug|x86
|
||||
|
@ -1026,7 +992,6 @@ Global
|
|||
{BAB1CAF4-C400-4A7F-A987-C576DE63CFFD} = {9333C63A-F64F-4797-82B3-017422668A5D}
|
||||
{1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C} = {9AD30620-667D-433C-9961-8D885EE7B762}
|
||||
{94994424-5F60-4CD8-ABA2-101779066208} = {9333C63A-F64F-4797-82B3-017422668A5D}
|
||||
{EFA96B3C-857E-4659-B942-6BEF7719F4CA} = {9333C63A-F64F-4797-82B3-017422668A5D}
|
||||
{7AEFC959-ED7C-4D96-9E92-72609B40FBE0} = {F1AFFFA7-28FE-4770-BA48-10D76F3E59BC}
|
||||
{6BD0BA4A-DE6D-3E87-8F83-63518C31ECD1} = {F1AFFFA7-28FE-4770-BA48-10D76F3E59BC}
|
||||
{A122EA02-4DE7-413D-BFBF-AF7DFC668DD6} = {B30036C4-D514-4E5B-A323-587A061772CE}
|
||||
|
|
Загрузка…
Ссылка в новой задаче