C#之强制转换小知识

需求

当你接收到一个字符串类型的数值的时候,你是如何得到你想要的数值的?是不是你觉得很简单,不就是转换一下吗?但是可以实现的方案有好几种,那么你会使用哪一种的,为什么使用这一种呐?不管你疑惑不疑惑,我是会疑惑我到底用哪一种更合适,这就是本文的目的所在。.

概述

本文主要来对比一下常见的几种强制转换的方法,比如对比int.Parse()和int.TryParse、Convert.ToInt32有什么区别。

int.Parse

该方法在命名空间System的Int32结构体下,该方法接收一个字符串,返回一个int类型的值。

int.Parse("");

先简单看下里面的写法

public static int Parse(string s)
{
  if (s == null)
     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
  return Number.ParseInt32((ReadOnlySpan<char>) s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}

从该方法可以看到如果传入的参数是null,直接就报错。接着进入ParseInt32方法,我们发现这里居然有调用了TryParseInt32,然后根据调用该方法的返回值判断,如果不是OK,那么就抛出异常ThrowOverflowOrFormatException。

internal static int ParseInt32(ReadOnlySpan<char> value,NumberStyles styles,NumberFormatInfo info)
{
  int result;
  Number.ParsingStatus int32 = Number.TryParseInt32(value, styles, info, out result);
  if (int32 != Number.ParsingStatus.OK)
     Number.ThrowOverflowOrFormatException(int32, TypeCode.Int32);
  return result;
}

再往下的代码TryParseInt32里面又调用了Number.TryParseInt32IntegerStyle,虽然我没看懂,不过不影响这次的目的。

总结:传入null时候,抛出异常ThrowArgumentNullException,传入转换失败的内容就抛出异常ThrowOverflowOrFormatException。转换成功就返回转换成功的值。

int.TryParse

该方法也在命名空间System的Int32结构体下,该方法接收一个字符串以及一个输出参数,并且返回一个bool类型的值。

var value = int.TryParse(str, out int result);

首先和上面不同的是,这个方法的入参是一个可为null的string字符串

public static bool TryParse([NotNullWhen(true)] string? s, out int result)
{
  if (s != null)
     return Number.TryParseInt32IntegerStyle((ReadOnlySpan<char>) s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result) == Number.ParsingStatus.OK;
  result = 0;
  return false;
}

可以看到如果参数传null,那么输出参数result就会赋值给0,至于为什么是0,是因为int类型的默认值就是0,如果是double.TryParse,那么默认值就是0.0,给一个默认的输出参数值后,返回了一个false,代表转换失败。具体的转换方法在于Number.TryParseInt32IntegerStyle

总结:传入null或者传入不能转换的值就返回false,并且输出参数为默认值。转换成功就返回true,并且输出参数返回转换后的值。

Convert.ToInt32

该方法也在命名空间System的Convert类下,该方法接收一个可为null字符串,并且返回一个int类型的值。

Convert.ToInt32(str);

进入该方法我们可以看到,如果传入的参数为null,那么就返回默认值。

public static int ToInt32(string? value)
{
 if (value == null)
  return 0;
 return int.Parse(value);
}

如果入参不为null,那么就调用int.Parse(value)的转换。

总结

  int.Parse int.TryParse Convert.ToInt32
入参为null 抛出ThrowArgumentNullException 返回false,输出参数为默认值 返回默认值
转换失败 抛出ThrowOverflowOrFormatException 返回false,输出参数为默认值 抛出ThrowOverflowOrFormatException
转换成功 返回转换成功后的值 返回true,输出参数为成功的值 返回转换成功后的值
参数为浮点数 不支持 不支持 四舍五入向上取整,4.2或者4.6返回5