如何分析一串成一个可空int
题
我想要分析一串成一个可空int。ie。我想要得到回int值string或空,如果它不能进行分析。
我希望,这将工作
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?
解决方案
int.TryParse
可能是一个稍微比较容易:
public static int? ToNullableInt(this string s)
{
int i;
if (int.TryParse(s, out i)) return i;
return null;
}
编辑 @Glenn int.TryParse
是"建立进入框架"。这和 int.Parse
都 的 的方式来分析串int.
其他提示
你可以做这一行,使用条件的操作者及事实上,你可以浇铸 null
一个空类型(两条线,如果没有一个预先存在的int你可以重复使用输出 TryParse
):
预C#7:
int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? Int32.Parse(stringVal) : (int?)null;
C#7最新的语法可以让你宣布一个输出变量的方法通话,本会变得更简单。
int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;
我有这个问题,我结束了这个(后一个 if
2 return
s洙啰嗦!):
int? ParseNInt (string val)
{
int i;
return int.TryParse (val, out i) ? (int?) i : null;
}
在一个更严重的注意,尽量不要混音 int
, ,这是一个C#关键词, Int32
, ,这是一个。净框架BCL类型的--虽然它的工作,它只是使代码看起来混乱。
格伦比:我更感兴趣了解如果 有一个内置的框架方法 将分析直接进入一个 nullable int?
那里是这种方法,将分析直接向一个可空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%");
NB: 有一个IsValid方法上的转换可使用,而不是捕获的例外(引例外情况不会导致 不必要的开销 如果预期的).不幸的是,它只适用。净4但仍有一个问题,它没有检查你的区域在验证正确的日期格式,请参阅 错误93559.
试试这个:
public static int? ParseNullableInt(this string value)
{
int intValue;
if (int.TryParse(value, out intValue))
return intValue;
return null;
}
老话题,但是,如何约:
public static int? ParseToNullableInt(this string value)
{
return String.IsNullOrEmpty(value) ? null : (int.Parse(value) as int?);
}
我喜欢这个更好的作为requriement在分析空,TryParse版本将不会引发一个错误,例如ToNullableInt32(XXX)。这可能引入不必要的沉默的错误。
我觉得我的解决方案是一个非常干净漂亮的解决方案:
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;
}
}
当然,这是一个通用的解决方案,只要求的仿制药的论点有一个静态的方法"的分析(string)".这个工作编号,布尔,日期时间,等等。
你可以忘记所有其他的答案-有一个很大的通用解决方案: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();
以下应工作的任何结构类型。它是根据关代码 马特Manela从MSDN论坛.作为墨菲点出例外处理可能会比较昂贵使用的类型专门TryParse方法。
public static bool TryParseStruct<T>(this string value, out Nullable<T> result)
where T: struct
{
if (string.IsNullOrEmpty(value))
{
result = new Nullable<T>();
return true;
}
result = default(T);
try
{
IConvertible convertibleString = (IConvertible)value;
result = new Nullable<T>((T)convertibleString.ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture));
}
catch(InvalidCastException)
{
return false;
}
catch (FormatException)
{
return false;
}
return true;
}
这些是基本的试验情况下,我使用。
string parseOne = "1";
int? resultOne;
bool successOne = parseOne.TryParseStruct<int>(out resultOne);
Assert.IsTrue(successOne);
Assert.AreEqual(1, resultOne);
string parseEmpty = string.Empty;
int? resultEmpty;
bool successEmpty = parseEmpty.TryParseStruct<int>(out resultEmpty);
Assert.IsTrue(successEmpty);
Assert.IsFalse(resultEmpty.HasValue);
string parseNull = null;
int? resultNull;
bool successNull = parseNull.TryParseStruct<int>(out resultNull);
Assert.IsTrue(successNull);
Assert.IsFalse(resultNull.HasValue);
string parseInvalid = "FooBar";
int? resultInvalid;
bool successInvalid = parseInvalid.TryParseStruct<int>(out resultInvalid);
Assert.IsFalse(successInvalid);
我会建议如下扩展方法用于字符串分析成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();
}
这个解决方案是通用的,没有反映的开销。
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);
}
我更感兴趣了解,如果有一个内置的框架方法,将分析直接进入一个可空int?
没有。
我觉得我应该分享我的这是一个比较通用的。
使用:
var result = "123".ParseBy(int.Parse);
var result2 = "123".ParseBy<int>(int.TryParse);
方案:
public static class NullableParse
{
public static Nullable<T> ParseBy<T>(this string input, Func<string, T> parser)
where T : struct
{
try
{
return parser(input);
}
catch (Exception exc)
{
return null;
}
}
public delegate bool TryParseDelegate<T>(string input, out T result);
public static Nullable<T> ParseBy<T>(this string input, TryParseDelegate<T> parser)
where T : struct
{
T t;
if (parser(input, out t)) return t;
return null;
}
}
第一个版本是较慢,因为它需要试一试-抓住,但是它看起来更清洁。如果它不会被称为多次与串无效的,它不是重要的。如果性能是一个问题,请注意,在使用TryParse方法,需要指定类型参数的ParseBy,因为它不能被推断编译器。我还要定义一个代表作出的关键词不可使用的内Func<>,但至少这时,编译器不需要一个明确的实例。
最后,可以使用它与其他结构,即小、DateTime Guid,等等。
我找到并适应一些代码,用于一般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;
}
}
}
public static void Main(string[] args)
{
var myString = "abc";
int? myInt = ParseOnlyInt(myString);
// null
myString = "1234";
myInt = ParseOnlyInt(myString);
// 1234
}
private static int? ParseOnlyInt(string s)
{
return int.TryParse(s, out var i) ? i : (int?)null;
}
你应该 从来没有 使用一个例外的,如果你没有的开销是可怕的。
变化TryParse解决问题-如果你想获得创造性的(让你的代码看起来更优雅)你也许可以做些什么与一个扩展方法在3.5但码将或多或少相同。
使用的各位代表,下列代码是能够提供可重复使用性,如果你发现自己需要的可空的分析对于多于一个结构类型。我们两个的.分析()and。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));
}
}
我已经想出了这一个,这已经满足我的要求(我希望我的扩展方法效仿尽可能接近返回的框架的TryParse,但没有尝试{}捉住{}块并没有编译器的抱怨推断一个空类型的框架内的方法)
private static bool TryParseNullableInt(this string s, out int? result)
{
int i;
result = int.TryParse(s, out i) ? (int?)i : null;
return result != null;
}
我建议代码波纹管。你可以工作,与例外,当转换的错误发生。
public static class Utils {
public static bool TryParse<Tin, Tout>(this Tin obj, Func<Tin, Tout> onConvert, Action<Tout> onFill, Action<Exception> onError) {
Tout value = default(Tout);
bool ret = true;
try {
value = onConvert(obj);
}
catch (Exception exc) {
onError(exc);
ret = false;
}
if (ret)
onFill(value);
return ret;
}
public static bool TryParse(this string str, Action<int?> onFill, Action<Exception> onError) {
return Utils.TryParse(str
, s => string.IsNullOrEmpty(s) ? null : (int?)int.Parse(s)
, onFill
, onError);
}
public static bool TryParse(this string str, Action<int> onFill, Action<Exception> onError) {
return Utils.TryParse(str
, s => int.Parse(s)
, onFill
, onError);
}
}
使用这种延伸方法在代码(填补int?年龄酒店的一个人类):
string ageStr = AgeTextBox.Text;
Utils.TryParse(ageStr, i => person.Age = i, exc => { MessageBox.Show(exc.Message); });
或
AgeTextBox.Text.TryParse(i => person.Age = i, exc => { MessageBox.Show(exc.Message); });
我意识到这是一个古老的话题,但是你不能简单:
(Nullable<int>)int.Parse(stringVal);
?