【发布时间】:2014-08-18 22:06:41
【问题描述】:
我需要编写一个具有以下语义的方法:
/// <summary>
/// Checks if <paramref name="x"/> is a boxed instance of a primitive integral type
/// whose numerical value equals to <paramref name="y"/>.
/// </summary>
/// <param name="x">An object reference. Can be <c>null</c>.</param>
/// <param name="y">A numerical value of type <see cref="ulong"/> to compare with.</param>
/// <returns>
/// <c>true</c> if <paramref name="x"/> refers to a boxed instance of type
/// <see cref="sbyte"/>, <see cref="short"/>, <see cref="int"/>, <see cref="long"/>,
/// <see cref="byte"/>, <see cref="ushort"/>, <see cref="uint"/>, or <see cref="ulong"/>,
/// whose numerical value equals to the numerical value of <paramref name="y"/>; otherwise, <c>false</c>.
/// </returns>
/// <remarks>
/// <para>
/// This method checks only for numeric equality, even if its arguments are of different runtime types
/// (e.g. <c>2L</c> is considered to be equal to <c>2UL</c>).
/// </para>
/// <para>
/// This method returns <c>false</c> if <paramref name="x"/> is <c>null</c>
/// or refers to an instance of a reference type or a boxed instance of a value type except
/// the primitive integral types listed above (e.g. it returns <c>false</c> if <paramref name="x"/>
/// refers to a boxed instance of an <c>enum</c> type, <see cref="bool"/>, <see cref="char"/>, <see cref="IntPtr"/>,
/// <see cref="UIntPtr"/>, <see cref="float"/>, <see cref="double"/>, <see cref="decimal"/>, or <see cref="BigInteger"/>).
/// </para>
/// <para>
/// This method should not throw any exceptions, or cause any observable side-effects
/// (e.g. invoke a method that could modify the state of an object referenced by <paramref name="x"/>).
/// </para>
/// </remarks>
[Pure]
public static bool NumericalEquals(object x, ulong y)
实施应尽可能快(假设输入数据中没有预期的偏向参数x 的某些类型或值),并且不应使用unsafe 代码或P/Invoke。当然,在最快的实现中,我更喜欢最简单、最短的。
我的解决方法如下:
public static bool NumericalEquals(object x, ulong y)
{
if (x is sbyte)
{
sbyte z = (sbyte)x;
return z >= 0 && y == (ulong)z;
}
if (x is short)
{
short z = (short)x;
return z >= 0 && y == (ulong)z;
}
if (x is int)
{
int z = (int)x;
return z >= 0 && y == (ulong)z;
}
if (x is long)
{
long z = (long)x;
return z >= 0 && y == (ulong)z;
}
if (x is byte)
{
return y == (byte)x;
}
if (x is ushort)
{
return y == (ushort)x;
}
if (x is uint)
{
return y == (uint)x;
}
if (x is ulong)
{
return y == (ulong)x;
}
return false;
}
您能提出更好的方法吗?
【问题讨论】:
-
您的代码目前似乎可以运行,并且您正在寻求改进它。一般来说,这些问题对于本网站来说过于固执己见,但您可能会在CodeReview.SE 找到更好的运气。记得阅读their requirements,因为他们比这个网站更严格。
-
这个问题似乎是题外话,因为它已经包含一个有效的解决方案。要请求对有效解决方案的批评,请考虑在 Code Review 上提问。
-
AFAIK 使这更快的唯一方法是消除装箱和拆箱。
-
@Serve 要求是生成最快的代码来解决问题。我的解决方案是否满足此要求并不是很明显,因此它可能无法“正常工作”。
-
@JeroenVannevel:在传递对象之前,您仍然需要一个 case 语句来将对象转换为正确的类型,因此您只是将复杂性推到了其他地方。
标签: c# .net performance equality primitive