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


当前回答

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

其他回答

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

老话题了,但下面这个话题怎么样:

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

我更喜欢这个作为解析null的需求,TryParse版本不会在例如ToNullableInt32(XXX)上抛出错误。这可能会引入不必要的静默错误。

更简洁的方法是编写一个单独的函数或扩展方法,但如果你只想要一行代码:

string s;
int? i = s == null ? (int?)null : int.Parse(s);

我发现并修改了Generic NullableParser类的一些代码。完整的代码在我的博客Nullable TryParse上

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace SomeNamespace
{
    /// <summary>
    /// A parser for nullable types. Will return null when parsing fails.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    ///
    public static class NullableParser<T> where T : struct
    {
        public delegate bool TryParseDelegate(string s, out T result);
        /// <summary>
        /// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method;
        /// </summary>
        /// <param name="text">Text to be parsed</param>
        /// <param name="result">Value is true for parse succeeded</param>
        /// <returns>bool</returns>
        public static bool TryParse(string s, out Nullable<T> result)
        {
            bool success = false;
            try
            {
                if (string.IsNullOrEmpty(s))
                {
                    result = null;
                    success = true;
                }
                else
                {
                    IConvertible convertableString = s as IConvertible;
                    if (convertableString != null)
                    {
                        result = new Nullable<T>((T)convertableString.ToType(typeof(T),
                            CultureInfo.CurrentCulture));
                        success = true;
                    }
                    else
                    {
                        success = false;
                        result = null;
                    }
                }
            }
            catch
            {
                success = false;
                result = null;
            }
            return success;
        }
    }
}

使用委托,如果您发现自己需要对多个结构类型进行可空解析,下面的代码能够提供可重用性。我在这里展示了. 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));
    }
  }