有没有尝试Convert.ToInt32 ...避免异常

时间:2013-08-14 08:55:16

标签: c# type-conversion

我想知道是否有一种“安全”的方法将对象转换为int避免异常。

我正在寻找像 public static bool TryToInt32(object value,out int result);

我知道我可以做这样的事情:

    public static bool TryToInt32(object value, out int result)
    {
        try
        {
            result = Convert.ToInt32(value);
            return true;
        }
        catch
        {
            result = 0;
            return false;
        }
    }

但我宁愿避免例外,因为它们正在减缓这个过程。

我认为这更优雅,但它仍然“便宜”。

    public static bool TryToInt32(object value, out int result)
    {
        if (value == null)
        {
            result = 0;
            return false;
        }

        return int.TryParse(value.ToString(), out result);
    }

任何人都有更好的主意吗?

更新:

这听起来有点像分裂头发搜索。但是将对象转换为字符串会强制实现者创建一个清晰的ToString()函数。

例如:

    public class Percentage
    {
        public int Value { get; set; }

        public override string ToString()
        {
            return string.Format("{0}%", Value);
        }
    }

        Percentage p = new Percentage();
        p.Value = 50;

        int v;

        if (int.TryParse(p.ToString(), out v))
        {

        }

这出错了,我可以在这里做两件事,或者像下面那样实现IConvertable。

    public static bool ToInt32(object value, out int result)
    {
        if (value == null)
        {
            result = 0;
            return false;
        }

        if (value is IConvertible)
        {
            result = ((IConvertible)value).ToInt32(Thread.CurrentThread.CurrentCulture);
            return true;
        }

        return int.TryParse(value.ToString(), out result);
    }

但IConvertible的ToInt32无法取消。因此,如果不可能,则无法避免异常。

或者两个:有没有办法检查对象是否包含隐式运算符?

这很差:

        if (value.GetType().GetMethods().FirstOrDefault(method => method.Name == "op_Implicit" && method.ReturnType == typeof(int)) != null)
        {
            result = (int)value;
            return true;
        }

7 个答案:

答案 0 :(得分:44)

int variable = 0;
int.TryParse(stringValue, out variable);

如果无法解析,变量将为0.请参阅http://msdn.microsoft.com/en-us/library/f02979c7.aspx

答案 1 :(得分:11)

从评论中迸发出来。响应为。如果没有抛出异常,你就无法做Convert.ToInt32(object)所做的事情。你可以做类似的事情(你已经做过了)。我要优化的唯一事情是value已经是int

if (value is int) 
    return (int)value;

您不能Convert.ToInt32(object),因为Convert.ToInt32(object)并不只是测试valueshort, int, long, ushort, ...然后投出它们。它会检查value是否为IConvertible。如果是,则使用IConvertible.ToInt32。可悲的是,界面IConvertible非常差:它没有非投掷方法(IConvertible.Try*

虽然很愚蠢(但可能不是太多),但有人可以制作一个UnixDateTime结构:( UnixTime是从1970-01-01午夜开始的秒数),其中IConvertible.ToInt32返回这个秒数,而ToString()返回格式化日期。所有int.TryParse(value.ToString(), out parsed)都会窒息,而Convert.ToInt32会完美无缺。

答案 2 :(得分:7)

这里不需要重新发明轮子。使用int.TryParse来实现目标。它返回一个bool来显示该值是否已被解析。如果解析,结果将保存在输出变量中。

int result;
object a = 5;
if(int.TryParse(a.ToString(),out result))
{
   Console.WriteLine("value is parsed");  //will print 5
}    

object b = a5;
if(int.TryParse(b.ToString(),out result))
{
    Console.WriteLine("value is parsed");  
}
else
{
    Console.WriteLine("input is not a valid integer");  //will print this   
}

答案 3 :(得分:3)

使用类型转换器的这个版本只会转换为字符串作为最后的手段,但也不会抛出异常:

public static bool TryToInt32(object value, out int result)
{
    if (value == null)
    {
        result = 0;
        return false;
    }
    var typeConverter =  System.ComponentModel.TypeDescriptor.GetConverter(value);
    if (typeConverter != null && typeConverter.CanConvertTo(typeof(int)))
    {
        var convertTo = typeConverter.ConvertTo(value, typeof(int));
        if (convertTo != null)
        {
            result = (int)convertTo;
            return true;
        }
    }
    return int.TryParse(value.ToString(), out result);
}

答案 4 :(得分:1)

我会混合使用你正在做的事情;

  • 检查对象是否为null - 返回false且值为0;
  • 尝试直接转换 - 如果成功,则返回true和转换后的值
  • 尝试解析value.ToString() - 如果成功,则返回true并解析值
  • 任何其他情况 - 返回false和值0,因为对象不可转换/可解析

结果代码:

public static bool TryToInt32(object value, out int result)
{
    result = 0;
    if (value == null)
    {
        return false;
    }

    //Try to convert directly
    try
    {
        result = Convert.ToInt32(value);
        return true;
    }
    catch
    {
        //Could not convert, moving on
    }

    //Try to parse string-representation
    if (Int32.TryParse(value.ToString(), out result))
    {
        return true;
    }

    //If parsing also failed, object cannot be converted or paresed
    return false;
}

答案 5 :(得分:0)

我写了这个烂摊子,看着它让我伤心。

using System;
using System.Globalization;

internal static class ObjectExt
{
    internal static bool TryConvertToDouble(object value, out double result)
    {
        if (value == null || value is bool)
        {
            result = 0;
            return false;
        }

        if (value is double)
        {
            result = (double)value;
            return true;
        }

        var text = value as string;
        if (text != null)
        {
            return double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
        }

        var convertible = value as IConvertible;
        if (convertible == null)
        {
            result = 0;
            return false;
        }

        try
        {
            result = convertible.ToDouble(CultureInfo.InvariantCulture);
            return true;
        }
        catch (Exception)
        {
            result = 0;
            return false;
        }
    }
}

编辑 请注意,当问题是int时,我回答为double,保持不变。也许对某人有用。

答案 6 :(得分:0)

返回可为null的int。这样就知道您是否解析了0。

int? value = int.TryParse(stringValue, out int outValue) 
    ? outValue
    : default(int?);