将对象转换为数字类型并检查值

时间:2013-01-31 10:56:29

标签: c# .net windows-8 windows-store-apps

我正在使用.NET for Windows Store应用程序编写pluralization框架。对于自定义格式化程序string Format(string format, params object[] args),我有以下代码:

public static bool IsExactlyOne(object n)
{
    if (n is Int16)
    {
        return (Int16)n == 1;
    }
    if (n is int) // Int32
    {
        return (int)n == 1;
    }
    if (n is long) // Int64
    {
        return (long)n == 1L;
    }
    if (n is UInt16)
    {
        return (UInt16)n == 1U;
    }
    if (n is uint) // UInt32
    {
        return (uint)n == 1U;
    }
    if (n is ulong) // UInt64
    {
        return (ulong)n == 1UL;
    }
    if (n is byte)
    {
        return (byte)n == 1;
    }
    if (n is sbyte)
    {
        return (sbyte)n == 1;
    }
    if (n is float)
    {
        return (float)n == 1.0F;
    }
    if (n is double)
    {
        return (double)n == 1.0D;
    }
    if (n is decimal)
    {
        return (decimal)n == 1.0M;
    }

    throw new ArgumentException("Unsupported type");
}

如你所见,它非常冗长。有没有办法简化这个?请注意:IConvertible 可用于Windows应用商店应用。

4 个答案:

答案 0 :(得分:2)

如何使用Dictionary来避免if

var dic = new Dictionary<Type, Func<object, bool>>()
                    {
                        {typeof(Int16), a => (Int16)a == 1},
                        {typeof(int), a => (int)a == 1},
                         ....
                    };

return dic[n.GetType()](n);

或使用dynamic

public static bool IsExactlyOne(dynamic n)
{
    return n == 1;
}         

答案 1 :(得分:1)

这应该可以正常工作:

    bool IsExactlyOne(object n)
    {
        int i;
        int.TryParse(n.ToString(), out i);
        return i == 1;
    }

除非处理像1.000000000000001这样的高精度数字,这是OP版本中已经存在的问题。

处理高精度的唯一方法是明确使用小数。

答案 2 :(得分:-1)

你去了:

public static bool IsExactlyOne(object n)
{
bool result = false;
try
{
result = Convert.ToDouble(n) == 1.0;
}
catch
{
}
return result;
}

答案 3 :(得分:-1)

请查看已接受的答案here

string value = "123.3";
double num;
if (!double.TryParse(value, out num))
  throw new InvalidOperationException("Value is not a number.");