我想在c#中解析一个字符串为可空int。ie。我想返回字符串的int值或null,如果它不能被解析。

我有点希望这能起作用

int? val = stringVal as int?;

但这行不通,我现在要做的是写这个扩展方法

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;
        }
    }
}   

有更好的办法吗?

编辑:感谢TryParse的建议,我确实知道这一点,但它的工作原理是一样的。我更感兴趣的是知道是否有一个内置的框架方法,将直接解析成一个可空的int?


当前回答

试试这个:

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

其他回答

这个解决方案是通用的,没有反射开销。

public static Nullable<T> ParseNullable<T>(string s, Func<string, T> parser) where T : struct
{
    if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(s.Trim())) return null;
    else return parser(s);
}

static void Main(string[] args)
{
    Nullable<int> i = ParseNullable("-1", int.Parse);
    Nullable<float> dt = ParseNullable("3.14", float.Parse);
}

[根据@sblom的建议更新为使用现代c#]

我遇到了这个问题,我最终得到了这个(毕竟,一个if和2返回是如此冗长!):

int? ToNullableInt (string val)
    => int.TryParse (val, out var i) ? (int?) i : null;

更严肃的一点是,尽量不要把int (c#关键字)和Int32 (. net Framework BCL类型)混在一起——尽管它可以工作,但它只会让代码看起来很乱。

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

这可以让你写出非常干净的代码,像这样:

string value = null;
int? x = value.ConvertOrDefault();

还有:

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();

如果没有必要,就不要使用异常——开销太大了。

TryParse的变体解决了这个问题——如果你想变得更有创意(让你的代码看起来更优雅),你可以在3.5中使用扩展方法做一些事情,但代码或多或少是一样的。

格伦·斯拉文:我更想知道是否 有一个内置的框架方法 这将直接解析为 nullable 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); }
}

这种方法仍然可以用于非空解析和可空解析:

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%");

注意:在转换器上有一个IsValid方法,您可以使用它来代替捕获异常(如果预期抛出的异常会导致不必要的开销)。不幸的是,它只从。net 4开始工作,但仍然有一个问题,它在验证正确的DateTime格式时不检查您的语言环境,请参阅bug 93559。