diff options
author | Tanner Gooding <tagoo@outlook.com> | 2018-11-29 12:15:43 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-29 12:15:43 -0800 |
commit | 211d963a42c8988770afa4d2edcbe9be0ed0b8a8 (patch) | |
tree | 88b907f2c9c89732feec22b502463a1b92c74674 | |
parent | 93d3f4c1f7f8a27c94aad68837dc8dda30c19b02 (diff) | |
download | coreclr-211d963a42c8988770afa4d2edcbe9be0ed0b8a8.tar.gz coreclr-211d963a42c8988770afa4d2edcbe9be0ed0b8a8.tar.bz2 coreclr-211d963a42c8988770afa4d2edcbe9be0ed0b8a8.zip |
Implement the Count property, the IEquatable and IFormattable interfaces, and the standard object overrides on Vector64/128/256<T> (#21259)
* Exposing the Count property on Vector64/128/256<T>
* Implementing IEquatable, IFormattable, and the object overrides on Vector64/128/256<T>
* Use StringBuilderCache, HashCode, and the provided format specifier
* Use StringBuilderCache.GetStringAndRelease and get the correct element when formatting Vector64/128/256<T>
3 files changed, 321 insertions, 45 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs index f3599a9842..da73f87e70 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics @@ -13,13 +15,25 @@ namespace System.Runtime.Intrinsics [DebuggerDisplay("{DisplayString,nq}")] [DebuggerTypeProxy(typeof(Vector128DebugView<>))] [StructLayout(LayoutKind.Sequential, Size = Vector128.Size)] - public readonly struct Vector128<T> where T : struct + public readonly struct Vector128<T> : IEquatable<Vector128<T>>, IFormattable + where T : struct { // These fields exist to ensure the alignment is 8, rather than 1. // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694) private readonly ulong _00; private readonly ulong _01; + /// <summary>Gets the number of <typeparamref name="T" /> that are in a <see cref="Vector128{T}" />.</summary> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public static int Count + { + get + { + ThrowIfUnsupportedType(); + return Vector128.Size / Unsafe.SizeOf<T>(); + } + } + /// <summary>Gets a new <see cref="Vector128{T}" /> with all elements initialized to zero.</summary> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> public static Vector128<T> Zero @@ -38,9 +52,7 @@ namespace System.Runtime.Intrinsics { if (IsSupported) { - var items = new T[ElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref items[0]), this); - return $"({string.Join(", ", items)})"; + return ToString(); } else { @@ -49,15 +61,6 @@ namespace System.Runtime.Intrinsics } } - internal static int ElementCount - { - get - { - ThrowIfUnsupportedType(); - return Vector128.Size / Unsafe.SizeOf<T>(); - } - } - internal static bool IsSupported { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -162,6 +165,34 @@ namespace System.Runtime.Intrinsics [CLSCompliant(false)] public Vector128<ulong> AsUInt64() => As<ulong>(); + /// <summary>Determines whether the specified <see cref="Vector128{T}" /> is equal to the current instance.</summary> + /// <param name="other">The <see cref="Vector128{T}" /> to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="other" /> is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public bool Equals(Vector128<T> other) + { + ThrowIfUnsupportedType(); + + for (int i = 0; i < Count; i++) + { + if (!((IEquatable<T>)(GetElement(i))).Equals(other.GetElement(i))) + { + return false; + } + } + + return true; + } + + /// <summary>Determines whether the specified object is equal to the current instance.</summary> + /// <param name="obj">The object to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector128{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override bool Equals(object obj) + { + return (obj is Vector128<T>) && Equals((Vector128<T>)(obj)); + } + /// <summary>Gets the element at the specified index.</summary> /// <param name="index">The index of the element to get.</param> /// <returns>The value of the element at <paramref name="index" />.</returns> @@ -171,7 +202,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -190,7 +221,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -201,6 +232,23 @@ namespace System.Runtime.Intrinsics return result; } + /// <summary>Gets the hash code for the instance.</summary> + /// <returns>The hash code for the instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override int GetHashCode() + { + ThrowIfUnsupportedType(); + + int hashCode = 0; + + for (int i = 0; i < Count; i++) + { + hashCode = HashCode.Combine(hashCode, GetElement(i).GetHashCode()); + } + + return hashCode; + } + /// <summary>Gets the value of the lower 64-bits as a new <see cref="Vector64{T}" />.</summary> /// <returns>The value of the lower 64-bits as a new <see cref="Vector64{T}" />.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> @@ -261,6 +309,50 @@ namespace System.Runtime.Intrinsics return Unsafe.As<Vector128<T>, T>(ref Unsafe.AsRef(in this)); } + /// <summary>Converts the current instance to an equivalent string representation.</summary> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override string ToString() + { + return ToString("G"); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format, IFormatProvider formatProvider) + { + ThrowIfUnsupportedType(); + + string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; + int lastElement = Count - 1; + + var sb = StringBuilderCache.Acquire(); + sb.Append('<'); + + for (int i = 0; i < lastElement; i++) + { + sb.Append(((IFormattable)(GetElement(i))).ToString(format, formatProvider)); + sb.Append(separator); + sb.Append(' '); + } + sb.Append(((IFormattable)(GetElement(lastElement))).ToString(format, formatProvider)); + + sb.Append('>'); + return StringBuilderCache.GetStringAndRelease(sb); + } + /// <summary>Converts the current instance to a new <see cref="Vector256{T}" /> with the lower 128-bits set to the value of the current instance and the upper 128-bits initialized to zero.</summary> /// <returns>A new <see cref="Vector256{T}" /> with the lower 128-bits set to the value of the current instance and the upper 128-bits initialized to zero.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs index a86ffb5db0..3731698308 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics @@ -13,7 +15,8 @@ namespace System.Runtime.Intrinsics [DebuggerDisplay("{DisplayString,nq}")] [DebuggerTypeProxy(typeof(Vector256DebugView<>))] [StructLayout(LayoutKind.Sequential, Size = Vector256.Size)] - public readonly struct Vector256<T> where T : struct + public readonly struct Vector256<T> : IEquatable<Vector256<T>>, IFormattable + where T : struct { // These fields exist to ensure the alignment is 8, rather than 1. // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694) @@ -22,6 +25,17 @@ namespace System.Runtime.Intrinsics private readonly ulong _02; private readonly ulong _03; + /// <summary>Gets the number of <typeparamref name="T" /> that are in a <see cref="Vector256{T}" />.</summary> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public static int Count + { + get + { + ThrowIfUnsupportedType(); + return Vector256.Size / Unsafe.SizeOf<T>(); + } + } + /// <summary>Gets a new <see cref="Vector256{T}" /> with all elements initialized to zero.</summary> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> public static Vector256<T> Zero @@ -40,9 +54,7 @@ namespace System.Runtime.Intrinsics { if (IsSupported) { - var items = new T[ElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref items[0]), this); - return $"({string.Join(", ", items)})"; + return ToString(); } else { @@ -51,15 +63,6 @@ namespace System.Runtime.Intrinsics } } - internal static int ElementCount - { - get - { - ThrowIfUnsupportedType(); - return Vector256.Size / Unsafe.SizeOf<T>(); - } - } - internal static bool IsSupported { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -164,6 +167,34 @@ namespace System.Runtime.Intrinsics [CLSCompliant(false)] public Vector256<ulong> AsUInt64() => As<ulong>(); + /// <summary>Determines whether the specified <see cref="Vector256{T}" /> is equal to the current instance.</summary> + /// <param name="other">The <see cref="Vector256{T}" /> to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="other" /> is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public bool Equals(Vector256<T> other) + { + ThrowIfUnsupportedType(); + + for (int i = 0; i < Count; i++) + { + if (!((IEquatable<T>)(GetElement(i))).Equals(other.GetElement(i))) + { + return false; + } + } + + return true; + } + + /// <summary>Determines whether the specified object is equal to the current instance.</summary> + /// <param name="obj">The object to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector256{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override bool Equals(object obj) + { + return (obj is Vector256<T>) && Equals((Vector256<T>)(obj)); + } + /// <summary>Gets the element at the specified index.</summary> /// <param name="index">The index of the element to get.</param> /// <returns>The value of the element at <paramref name="index" />.</returns> @@ -173,7 +204,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -192,7 +223,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -203,6 +234,23 @@ namespace System.Runtime.Intrinsics return result; } + /// <summary>Gets the hash code for the instance.</summary> + /// <returns>The hash code for the instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override int GetHashCode() + { + ThrowIfUnsupportedType(); + + int hashCode = 0; + + for (int i = 0; i < Count; i++) + { + hashCode = HashCode.Combine(hashCode, GetElement(i).GetHashCode()); + } + + return hashCode; + } + /// <summary>Gets the value of the lower 128-bits as a new <see cref="Vector128{T}" />.</summary> /// <returns>The value of the lower 128-bits as a new <see cref="Vector128{T}" />.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> @@ -262,5 +310,49 @@ namespace System.Runtime.Intrinsics ThrowIfUnsupportedType(); return Unsafe.As<Vector256<T>, T>(ref Unsafe.AsRef(in this)); } + + /// <summary>Converts the current instance to an equivalent string representation.</summary> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override string ToString() + { + return ToString("G"); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format, IFormatProvider formatProvider) + { + ThrowIfUnsupportedType(); + + string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; + int lastElement = Count - 1; + + var sb = StringBuilderCache.Acquire(); + sb.Append('<'); + + for (int i = 0; i < lastElement; i++) + { + sb.Append(((IFormattable)(GetElement(i))).ToString(format, formatProvider)); + sb.Append(separator); + sb.Append(' '); + } + sb.Append(((IFormattable)(GetElement(lastElement))).ToString(format, formatProvider)); + + sb.Append('>'); + return StringBuilderCache.GetStringAndRelease(sb); + } } } diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs index 0bb028602a..b19054917b 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics @@ -13,12 +15,24 @@ namespace System.Runtime.Intrinsics [DebuggerDisplay("{DisplayString,nq}")] [DebuggerTypeProxy(typeof(Vector64DebugView<>))] [StructLayout(LayoutKind.Sequential, Size = Vector64.Size)] - public readonly struct Vector64<T> where T : struct + public readonly struct Vector64<T> : IEquatable<Vector64<T>>, IFormattable + where T : struct { // These fields exist to ensure the alignment is 8, rather than 1. // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694) private readonly ulong _00; + /// <summary>Gets the number of <typeparamref name="T" /> that are in a <see cref="Vector64{T}" />.</summary> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public static int Count + { + get + { + ThrowIfUnsupportedType(); + return Vector64.Size / Unsafe.SizeOf<T>(); + } + } + /// <summary>Gets a new <see cref="Vector64{T}" /> with all elements initialized to zero.</summary> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> public static Vector64<T> Zero @@ -36,9 +50,7 @@ namespace System.Runtime.Intrinsics { if (IsSupported) { - var items = new T[ElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref items[0]), this); - return $"({string.Join(", ", items)})"; + return ToString(); } else { @@ -47,15 +59,6 @@ namespace System.Runtime.Intrinsics } } - internal static int ElementCount - { - get - { - ThrowIfUnsupportedType(); - return Vector64.Size / Unsafe.SizeOf<T>(); - } - } - internal static bool IsSupported { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -160,6 +163,34 @@ namespace System.Runtime.Intrinsics [CLSCompliant(false)] public Vector64<ulong> AsUInt64() => As<ulong>(); + /// <summary>Determines whether the specified <see cref="Vector64{T}" /> is equal to the current instance.</summary> + /// <param name="other">The <see cref="Vector64{T}" /> to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="other" /> is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public bool Equals(Vector64<T> other) + { + ThrowIfUnsupportedType(); + + for (int i = 0; i < Count; i++) + { + if (!((IEquatable<T>)(GetElement(i))).Equals(other.GetElement(i))) + { + return false; + } + } + + return true; + } + + /// <summary>Determines whether the specified object is equal to the current instance.</summary> + /// <param name="obj">The object to compare with the current instance.</param> + /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector64{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override bool Equals(object obj) + { + return (obj is Vector64<T>) && Equals((Vector64<T>)(obj)); + } + /// <summary>Gets the element at the specified index.</summary> /// <param name="index">The index of the element to get.</param> /// <returns>The value of the element at <paramref name="index" />.</returns> @@ -169,7 +200,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -188,7 +219,7 @@ namespace System.Runtime.Intrinsics { ThrowIfUnsupportedType(); - if ((uint)(index) >= (uint)(ElementCount)) + if ((uint)(index) >= (uint)(Count)) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -199,6 +230,23 @@ namespace System.Runtime.Intrinsics return result; } + /// <summary>Gets the hash code for the instance.</summary> + /// <returns>The hash code for the instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override int GetHashCode() + { + ThrowIfUnsupportedType(); + + int hashCode = 0; + + for (int i = 0; i < Count; i++) + { + hashCode = HashCode.Combine(hashCode, GetElement(i).GetHashCode()); + } + + return hashCode; + } + /// <summary>Converts the current instance to a scalar containing the value of the first element.</summary> /// <returns>A scalar <typeparamref name="T" /> containing the value of the first element.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> @@ -208,6 +256,50 @@ namespace System.Runtime.Intrinsics return Unsafe.As<Vector64<T>, T>(ref Unsafe.AsRef(in this)); } + /// <summary>Converts the current instance to an equivalent string representation.</summary> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public override string ToString() + { + return ToString("G"); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + /// <summary>Converts the current instance to an equivalent string representation using the specified format.</summary> + /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> + /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> + /// <returns>An equivalent string representation of the current instance.</returns> + /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> + public string ToString(string format, IFormatProvider formatProvider) + { + ThrowIfUnsupportedType(); + + string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; + int lastElement = Count - 1; + + var sb = StringBuilderCache.Acquire(); + sb.Append('<'); + + for (int i = 0; i < lastElement; i++) + { + sb.Append(((IFormattable)(GetElement(i))).ToString(format, formatProvider)); + sb.Append(separator); + sb.Append(' '); + } + sb.Append(((IFormattable)(GetElement(lastElement))).ToString(format, formatProvider)); + + sb.Append('>'); + return StringBuilderCache.GetStringAndRelease(sb); + } + /// <summary>Converts the current instance to a new <see cref="Vector128{T}" /> with the lower 64-bits set to the value of the current instance and the upper 64-bits initialized to zero.</summary> /// <returns>A new <see cref="Vector128{T}" /> with the lower 64-bits set to the value of the current instance and the upper 64-bits initialized to zero.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> |