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

Jer*_*gen 41 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我认为这更优雅,但它仍然"便宜".

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

    return int.TryParse(value.ToString(), out result);
}
Run Code Online (Sandbox Code Playgroud)

谁有更好的主意?

更新:

这听起来有点像分裂头发搜索.但是将对象转换为字符串会强制实现者创建一个清晰的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))
{

}
Run Code Online (Sandbox Code Playgroud)

这出错了,我可以在这里做两件事,或者像下面那样实现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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

这很差:

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

ran*_*uwe 46

int variable = 0;
int.TryParse(stringValue, out variable);
Run Code Online (Sandbox Code Playgroud)

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

  • 更可靠:`int variable = int.TryParse(stringValue,out variable)?变量:0` (15认同)
  • 如果将对象传递给TryParse,则会失败. (7认同)

xan*_*tos 11

刺激评论.答案是否定的.如果没有Convert.ToInt32(object)抛出异常,你就无法做到这一点.你可以做类似的事情(你已经做过了).我唯一要优化的是value已经是的情况int.

if (value is int) 
    return (int)value;
Run Code Online (Sandbox Code Playgroud)

你不能这样做的Convert.ToInt32(object),因为Convert.ToInt32(object)不只是测试,如果valueshort, int, long, ushort, ...再投他们.它检查,如果valueIConvertible.如果是,则使用IConvertible.ToInt32.可悲的是界面IConvertible很差:它没有非抛出方法(IConvertible.Try*)

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


Ehs*_*san 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   
}
Run Code Online (Sandbox Code Playgroud)

  • @KaiHartmann是的它需要一个字符串.如果你有对象,你必须首先调用ToString方法.更新了我的回答. (3认同)

Jer*_*mas 5

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • +1 是一个有趣且不同的答案。但这确实是使用相同的旧 IConvertible 方法的*非常*迂回的方式。这里的部分问题也是 `CanConvertTo` 方法。它根本没有做我们想要的 - 我们希望答案取决于实际值:我们希望 long 可以转换为 int *如果存储在 long 中的值适合 int*。如果尝试将 `long.MaxValue` 转换为 int,该方法会抛出溢出异常,因为 `CanConvertTo` 不会像你想象的那样做,实际上它会为 **all** 原始类型返回 true! (3认同)