我觉得每次使用 TryParse
都会导致代码变得有些丑陋。主要是我这样使用:
int value;
if (!int.TryParse(someStringValue, out value))
{
value = 0;
}
有没有更优雅的解决方案来解析所有基本数据类型,具体来说,是否有一种方法可以在一行中进行安全失败解析?通过安全失败,我假设在解析失败时设置默认值而不会引发异常。
顺便说一下,这是为必须执行某些操作即使解析失败的情况,只使用默认值。
我觉得每次使用 TryParse
都会导致代码变得有些丑陋。主要是我这样使用:
int value;
if (!int.TryParse(someStringValue, out value))
{
value = 0;
}
有没有更优雅的解决方案来解析所有基本数据类型,具体来说,是否有一种方法可以在一行中进行安全失败解析?通过安全失败,我假设在解析失败时设置默认值而不会引发异常。
顺便说一下,这是为必须执行某些操作即使解析失败的情况,只使用默认值。
如果您喜欢单行代码,这是有效的并且可能更适合您:
int i = int.TryParse(s, out i) ? i : 42;
如果无法解析字符串s
,则将i
的值设置为42
,否则将i = i
。
Dim i As Int32 = If(Int32.TryParse("nonum", i), i, 42)
。谢谢。 - Tim Schmelterreturn int.TryParse(s, out int i) ? i : 42;
- BalintPogatsaTryParse
返回false时执行额外的赋值,但三元运算符要求你考虑两种情况。 - Kyle Delaney直接使用扩展方法怎么样?
public static class Extensions
{
public static int? TryParse(this string Source)
{
int result;
if (int.TryParse(Source, out result))
return result;
else
return null;
}
}
使用新的C#语法,在单行中:
public static int? TryParse(this string Source) => int.TryParse(Source, out int result) ? result : (int?)null;
使用方法:
v = "234".TryParse() ?? 0
TryParse
方法的 Maybe
类。int? value = Maybe.ToInt("123");
if (value == null)
{
// not a number
}
else
{
// use value.Value
}
或者在行内指定默认值:
int value = Maybe.ToInt("123") ?? 0;
请注意 Nullable<int>
/int?
和 int
之间的区别。
更多信息请参见http://www.kodefuguru.com/post/2010/06/24/TryParse-vs-Convert.aspx
C# 7中有一个不错的小功能,声明表达式,所以在C# 7中可以用如下语法代替原来的写法:
int x;
if (int.TryParse("123", out x))
{
DoSomethingWithX(x);
}
我们可以使用:
if (int.TryParse("123", out int x))
{
DoSomethingWithX(x);
}
对我来说很不错 :)
在一行中使用C#7
int.TryParse(s, out var i) ? i : (int?)null;
示例方法:
public static int? TryParseSafe(string s)
{
return int.TryParse(s, out var i) ? i : (int?)null;
}
int value;
int.TryParse(someStringValue, out value);
因为 Int32.TryParse() 的文档中说明,如果解析失败,value
会被设置为0。
public T Convert<T>(string input, T defaultVal)
{
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
if(converter != null)
{
return (T)converter.ConvertFromString(input);
}
return defaultVal;
}
public T Convert<T>(string input)
{
return Convert(input, default(T));
}
T
约束为结构体,并使用 Nullable
(如 @skarmats 的答案所示)。Convert<T>(string input, T defaultVal = default(T))
,第二种方法可以被删除。 - dav_i我对这个答案有一个小的改进建议,就是在下面的片段中创建一个扩展方法和TryConvert扩展方法:
public static T Convert<T>(this string input, T defaultVal)
{
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T) converter.ConvertFromString(input);
}
return defaultVal;
}
public static T Convert<T>(this string input)
{
return Convert(input, default(T));
}
public static bool TryConvert<T>(this string input, T defaultVal, out T result)
{
try
{
result = Convert(input, defaultVal);
return true;
}
catch (Exception exception)
{
result = defaultVal;
return string.IsNullOrEmpty(input);
}
}
然后我们可以像片段一样使用它
if (someValue.TryConvert(1, out var result))
{
}
result
数据类型会根据 defaultVal 自动确定。
对于尝试使用F#的C#开发人员来说,这是一个令人惊喜的好消息。TryParse方法返回一个包含布尔值和值的元组。
TryParse
中使用ref参数。 - Tim Schmelter