我想在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?


当前回答

使用委托,如果您发现自己需要对多个结构类型进行可空解析,下面的代码能够提供可重用性。我在这里展示了. parse()和. tryparse()版本。

这是一个示例用法:

NullableParser.TryParseInt(ViewState["Id"] as string);

这是让你到达那里的代码……

public class NullableParser
  {
    public delegate T ParseDelegate<T>(string input) where T : struct;
    public delegate bool TryParseDelegate<T>(string input, out T outtie) where T : struct;
    private static T? Parse<T>(string input, ParseDelegate<T> DelegateTheParse) where T : struct
    {
      if (string.IsNullOrEmpty(input)) return null;
      return DelegateTheParse(input);
    }
    private static T? TryParse<T>(string input, TryParseDelegate<T> DelegateTheTryParse) where T : struct
    {
      T x;
      if (DelegateTheTryParse(input, out x)) return x;
      return null;
    }
    public static int? ParseInt(string input)
    {
      return Parse<int>(input, new ParseDelegate<int>(int.Parse));
    }
    public static int? TryParseInt(string input)
    {
      return TryParse<int>(input, new TryParseDelegate<int>(int.TryParse));
    }
    public static bool? TryParseBool(string input)
    {
      return TryParse<bool>(input, new TryParseDelegate<bool>(bool.TryParse));
    }
    public static DateTime? TryParseDateTime(string input)
    {
      return TryParse<DateTime>(input, new TryParseDelegate<DateTime>(DateTime.TryParse));
    }
  }

其他回答

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

Pre C # 7:

int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? tempVal : (int?)null;

c# 7更新的语法允许你在方法调用中声明一个输出变量,这变得更加简单。

int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;

试试这个:

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

我建议以下扩展方法将字符串解析为int值,并在解析不可能的情况下定义默认值:

public static int ParseInt(this string value, int defaultIntValue = 0)
        {
            return int.TryParse(value, out var parsedInt) ? parsedInt : defaultIntValue;
        }

public static int? ParseNullableInt(this string value)
        {
            if (string.IsNullOrEmpty(value))
                return null;

            return value.ParseInt();
        }

你可以忘记所有其他答案——有一个很好的通用解决方案: 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();

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

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