假设我有一个方法采用对象的参数来打印数字:
object target = Console.ReadLine();
PrintNumber(target);
public void PrintNumber(object target)
{
int number = 0;
if(int.TryParse(target.ToString(), out number))
{
Console.WriteLine(number);
}
}
如果我只想使用:
Console.WriteLine((int)target);
但它不起作用并抛出异常,为什么我们应该使用TryParse方法?
答案 0 :(得分:7)
为什么我们应该使用TryParse方法?
因为当您使用TryParse
方法时,它不会为您的代码 IF 引发异常转换失败。如果你以(int)target
的方式进行转换,如果转换为int
失败则会抛出异常
答案 1 :(得分:2)
您无法以这种方式明确转换为Object
类型。您需要使用Convert
类。
Console.WriteLine(Convert.toInt32(target));
答案 2 :(得分:2)
只是为了更多地充实这一点 -
使用C#进行转换将尝试找到合适的转换运算符。如果target
对象是int
或具有适当的投射操作符(例如,如果它是byte
或short
)那么您就是好的 - 它将在运行时正确转换。但是,如果没有运算符,它将抛出InvalidCastException
- 例如target
是string
(没有良好的默认方式来投射string
}到int
s - string
"这是一个字符串"强制转换为?)。
例外情况很好,但应该在发生意外情况时予以保留。它不应该是如此出乎意料,以至于用户输入可能是数字也可能不是数字(或任何string
可能是数字也可能不是数字)。因此,为此代码编写try/catch
块是过度的,并且会比以某种方式检查string
是否为数字并做出决定(这可能是您可能的话)更加耗费资源。试着用你的try/catch
阻止。你可以通过检查string
是否为null然后在其上运行RegEx或迭代字符寻找非数字字符来做到这一点(这对于{{1来说不是很难)但是,对于允许使用科学记数法的数字,或者允许或不允许使用符号/空格/逗号/小数等等的数字格式,它会变得更复杂。您也可以尝试调用int
,但这会让您再次回到异常问题(请记住:抛出和捕获异常比检查布尔值更昂贵。)
因此.NET框架为您提供了更好的选择:.Parse()
。某些类型的某些重载甚至允许您指定格式或样式(例如在TryParse
和float.TryParse()
上)。通过这种方式,您可以通过检查布尔值来更有效地控制程序流,而无需在每次需要检查字符串是数字还是日期或时间等时重新发明轮子。而且由于大多数对象都可以轻松转换为字符串,因此更好的。您的程序现在可以决定如何处理无效输入,而不是必然抛出异常(这可能是过度杀伤)。即使你真的想在输入不是数字时抛出异常,你也可以抛出一个更好/更具体的异常 - 而不是抛出DateTime.TryParse() / DateTime.TryParseExact()
,你可能会抛出类似自定义InvalidCastException
的东西很好的消息,解释什么参数/参数/节点不正确。
要考虑的另一个选择是,如果由于某种原因,您的方法必须采用ValidationFailureException
(可能它符合您无法修改的界面定义),但是您相信你的输入通常是一个int,你可以做类似的事情
object
请注意,由于var intTarget = target as int?
if (intTarget != null)
{
Console.WriteLine(intTarget);
}
可能会导致as
,因此您必须使用可为空的int。这可能对此特定情况没有帮助,因为如果null
失败,您仍希望最终使用TryParse
- 但是当您处理更复杂的事情时它可能会有用缺少任何框架提供的as
方法的类的对象。但是请注意,除了检查之外,这更像是铸造 - TryParse
如果TryParse
真正 是具有数字字符的字符串,则可以正常工作; object
仅在as
真正 object
(或int
)时才有效:
int?