문제

내가 원하는 문자열을 구문 분석으로 널 int C#.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?

도움이 되었습니까?

해결책

int.TryParse 아마도 조금 더 쉽:

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

편집 @글렌 int.TryParse 은"내장 된 프레임워크"입니다.고 int.Parse 는 방법을 분석하는 문자열을 수.

다른 팁

이 작업을 수행할 수 있습니 하나의 라인을 사용하여 조건부 연산자 및 수 있다는 사실을 캐스팅 null 을 널 타입(두 줄이 없다면 기존 int 에 재사용할 수 있의 출력 TryParse):

Pre 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 returns 수 장황한!):

int? ParseNInt (string val)
{
    int i;
    return int.TryParse (val, out i) ? (int?) i : null;
}

에 더 심각하고,혼합하지 않도록 노력 int, 는 C#키워드로, Int32, 는 것입니다.NET Framework BCL 유형-그것은 작동 하지만,그것은 단지 코드 보이 지저분하다.

글렌 슬라:나는 아는 것에 관심이 있는 경우 가 내장된 프레임워크 방법 는 것이 직접 구문 분석 널 int?

이 접근하는 것이 직접 구문 분석하여 널 int(지만 int)값이 유효한 다음과 같 null 거나 빈 문자열이나 예외를 위한 잘못된 값 그래서 당신이 잡을 필요가있을 제외하고 기본 값을 반환한 상황:

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

이 방법을 계속 사용할 수 있습니다 null 을 허용하지 않는 구문 분석뿐만 아니라 널:

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 방법에 변환기를 사용할 수 있습을 캡처하는 대신 exception(던지 예외가 결과에 불필요한 오버헤드 는 경우 예상되는).불행하게도 그것은 작동합니다.순 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 는 구문 분석하 null,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;
    }
}

물론 이것은 일반적인 솔루션을 필요로 하는 제네릭의 인수에는 정적 방법"Parse(string)".이 작품에 대한 숫자,부울,날짜/시간,etc.

var result = int.TryParse(foo, out var f) ? f : default(int?);

원:

잊을 수 있는 다른 모든 답변-수있는 좋은 일반적인 솔루션: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;
    }
}

첫번째 버전이 느리기 때문에 그것이 필요합 try-catch 지만 청소기입니다.되지 않는 경우 여러 번 호출하는 잘못된 문자열을,그것은 중요하지 않습니다.성능이 문제가 되는 경우에는주의하시기 바랍를 사용하는 경우 TryParse 방법은,당신은 유형을 지정해야의 매개 변수 ParseBy 으로 유추할 수 없습으로 컴파일러입니다.도가 정의 대리자로 키워드를 사용할 수 없습에 Func<>,하지만 적어도 이시 컴파일러 명시적인 동의를 요구하지 않 인스턴스입니다.

마지막으로,당신은 그것을 사용할 수 있는 다른 구조체뿐만 아니라,즉수,날짜/시간,Guid,etc.

내가 발견하고 적응하는 코드에 대한 일반적인 NullableParser 클래스입니다.체 코드가 나 블로그 널 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 지만 코드는 것이 더 많거나 적은 동일합니다.

대리자를 사용하여,다음과 같은 코드를 제공할 수 있 재사용하는 경우 당신은 자신을 찾을 필요로 하는 널 분석에 대한 하나 이상의 구조는 유형입니다.나는 모두 표시됩니다.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));
    }
  }

나는 이 한,만족 하는 나의 요구 사항(가로 확장하는 방법을 에뮬레이션으로 가능한 한 가까운 반환 프레임워크의 TryParse 지만,try{}catch{}블록고없이 컴파일러에 대해 불평추 null 허용 입력 프레임워크 내에서 방법)

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?Age 속의 사람은 클래스):

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

?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top