如何将字符串解析为可空的int

Gle*_*ven 288 .net c# string nullable .net-3.5

我想在C#中将字符串解析为可以为空的int.即.我想要返回字符串的int值,如果无法解析,则返回null.

我有点希望这会奏效

int? val = stringVal as int?;
Run Code Online (Sandbox Code Playgroud)

但这不起作用,所以我现在这样做的方式是我写了这个扩展方法

public static int? ParseNullableInt(this string value)
{
    if (value == null || value.Trim() == string.Empty)
    {
        return null;
    }
    else
    {
        try
        {
            return int.Parse(value);
        }
        catch
        {
            return null;
        }
    }
}   
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?

编辑: 感谢TryParse的建议,我确实知道这一点,但它的结果大致相同.我更感兴趣的是知道是否有一个内置的框架方法可以直接解析为可以为空的int?

Mat*_*ton 344

int.TryParse 可能有点容易:

public static int? ToNullableInt(this string s)
{
    int i;
    if (int.TryParse(s, out i)) return i;
    return null;
}
Run Code Online (Sandbox Code Playgroud)

编辑 @Glenn int.TryParse"内置于框架中".它int.Parse字符串解析为int的方法.

  • 少一行:返回Int32.TryParse(s,out i)?我:null; (80认同)
  • @Chris,编译器不喜欢你的内联if语句(这些类型不兼容:'int':'null').我不得不修改它:返回Int32.TryParse(s,out i)?(int?)i:null; (52认同)
  • Int32只是int的别名.我会使用int.TryParse来保持正在使用的类型.如果/当int用于表示不同的位长整数(已发生),则Int32将不与int对齐. (8认同)
  • return int.TryParse(s,out i)?(int?)i:null; (3认同)
  • "a"将返回null,但它不是int并且应该抛出异常 (2认同)

McK*_*eG1 166

您可以使用条件运算符和可以null转换为可空类型的事实在一行中执行此操作(两行,如果您没有预先存在的int,则可以重用输出TryParse):

前C#7:

int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? Int32.Parse(stringVal) : (int?)null;
Run Code Online (Sandbox Code Playgroud)

使用C#7的更新语法,您可以在方法调用中声明输出变量,这甚至更简单.

int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;
Run Code Online (Sandbox Code Playgroud)

  • return`int.TryParse(val,out i)?i:default(int?);` (19认同)
  • 这里没有评估顺序副作用.所有步骤都是明确排序和正确的. (11认同)
  • @ Bart的"答案"是最好的! (6认同)
  • 我认为这取决于你对条件运算符的看法.我的心智模型是if-else等价的几乎是语法糖,在这种情况下,我的版本和Matt的接近相同,他更明确,我的更多cmopact. (4认同)
  • 现在在C#6中,它可以是一行!Int32.TryParse(stringVal,out var tempVal)?tempVal:(int?)null; (4认同)
  • 这里只是注意 - c#6没有附带此功能,所以不要尝试声明var inline(http://stackoverflow.com/questions/31724163/c-sharp-6-0-tryparse-with-out -var-PARAM) (3认同)
  • 你可以 - 但是当你可以通过使用Matt的语法使顺序依赖显而易见时,依赖于副作用和评估顺序是很讨厌的.顺便说一句,为这个和类似的表达式使用default(int?)是很方便的,以避免源于`null`的无类型性质的类型推断错误,而不需要插入可能实际执行代码的强制转换. (2认同)

Duc*_*boy 33

抱歉,无法抗拒 - 有这个问题,谷歌把我带到了这里,但我最终得到了这个(毕竟,if和2 返回 s太啰嗦了!):

int? ParseNInt (string val)
{
    int i;
    return int.TryParse (val, out i) ? (int?) i : null;
}
Run Code Online (Sandbox Code Playgroud)

更严重的是,尽量不要将int(这是一个C#关键字)与Int32(一种.NET Framework BCL类型)混合使用 - 尽管它有效,但它只会让代码看起来很乱.

  • 不太确定这实际上会转化为编译后效果更好的任何东西 (3认同)
  • 因此为了完整性;-)`int?ParseNInt(字符串val)=> int.TryParse(val,out var i)?(int?)i:null;` (2认同)

Mic*_*ael 15

Glenn Slaven:我更想知道是否有一个内置的框架方法可以直接解析为可以为空的int?

如果值有效(如null或空字符串),则此方法将直接解析为可空int(而不仅仅是int),但会为无效值引发异常,因此您需要捕获异常并返回默认值对于那些情况:

public static T Parse<T>(object value)
{
    try { return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value.ToString()); }
    catch { return default(T); }
}
Run Code Online (Sandbox Code Playgroud)

这种方法仍然可以用于非可空的解析以及可以为空的:

enum Fruit { Orange, Apple }
var res1 = Parse<Fruit>("Apple");
var res2 = Parse<Fruit?>("Banana");
var res3 = Parse<int?>("100") ?? 5; //use this for non-zero default
var res4 = Parse<Unit>("45%");
Run Code Online (Sandbox Code Playgroud)

注意:您可以使用转换器上的IsValid方法而不是捕获异常(如果需要,抛出的异常会导致不必要的开销).不幸的是它只能用于.NET 4,但是在验证正确的DateTime格式时它仍然没有检查你的语言环境的问题,参见bug 93559.


Jaa*_*a H 10

var result = int.TryParse(foo, out var f) ? f : default(int?);
Run Code Online (Sandbox Code Playgroud)

资料来源:

  • tryparse 期望被放入一个不可为空的变量中,所以你的 default(int?) 不会强制 var 可以为空吗? (2认同)

Jos*_*gle 8

试试这个:

public static int? ParseNullableInt(this string value)
{
    int intValue;
    if (int.TryParse(value, out intValue))
        return intValue;
    return null;
}
Run Code Online (Sandbox Code Playgroud)


小智 8

老话题,但怎么样:

public static int? ParseToNullableInt(this string value)
{
     return String.IsNullOrEmpty(value) ? null : (int.Parse(value) as int?);
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢这个作为解析null的请求,TryParse版本不会在例如ToNullableInt32(XXX)上抛出错误.这可能会引入有害的无声错误.

  • 如果 value 是非数字,int.Parse 会抛出异常,这与返回 null 不同。 (3认同)
  • 这正是重点 - 如果字符串无法解析为“int”,它应该返回“null”,而不是抛出异常。 (2认同)

小智 5

我觉得我的解决方案是一个非常干净而且不错的解决方案:

public static T? NullableParse<T>(string s) where T : struct
{
    try
    {
        return (T)typeof(T).GetMethod("Parse", new[] {typeof(string)}).Invoke(null, new[] { s });
    }
    catch (Exception)
    {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这是一个通用解决方案,仅要求generics参数具有静态方法“ Parse(string)”。这适用于数字,布尔值,日期时间等。


Pav*_*dek 5

您可能会忘记所有其他答案-有一个很好的通用解决方案:http : //cleansharp.de/wordpress/2011/05/generischer-typeconverter/

这使您可以编写非常干净的代码,如下所示:

string value = null;
int? x = value.ConvertOrDefault();
Run Code Online (Sandbox Code Playgroud)

并且:

object obj = 1;  

string value = null;
int x = 5;
if (value.TryConvert(out x))
    Console.WriteLine("TryConvert example: " + x); 

bool boolean = "false".ConvertOrDefault();
bool? nullableBoolean = "".ConvertOrDefault();
int integer = obj.ConvertOrDefault();
int negativeInteger = "-12123".ConvertOrDefault();
int? nullableInteger = value.ConvertOrDefault();
MyEnum enumValue = "SecondValue".ConvertOrDefault();

MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault();
Run Code Online (Sandbox Code Playgroud)