Jak analizować ciąg do wartości pustych int

głosy
246

Ja chcąc zanalizować ciąg do int wartości pustych w języku C #. to znaczy. Chcę wrócić albo wartość int łańcucha lub NULL jeśli nie może być analizowany.

Miałam nadzieję, że to będzie działać

int? val = stringVal as int?;

Ale to nie będzie działać, tak jak ja to robię teraz jest Pisałem tę metodę rozszerzenia

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

Czy istnieje lepszy sposób to zrobić?

EDIT: Dzięki za sugestie TryParse, ja wiedziałem o tym, ale to działało tak samo. Jestem bardziej zainteresowany wiedząc, jeśli istnieje wbudowanej metody ramy, które będą analizować bezpośrednio do wartości pustych int?

Utwórz 05/09/2008 o 01:22
źródło użytkownik
W innych językach...                            


21 odpowiedzi

głosy
297

int.TryParse to chyba ciut łatwiej:

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

Edycja @Glenn int.TryParsejest „zbudowany w ramy”. To i int.Parsesą sposób analizowania ciągi do wskazówki.

Odpowiedział 05/09/2008 o 01:25
źródło użytkownik

głosy
125

Można to zrobić w jednej linii, za pomocą operatora warunkowego oraz fakt, że można oddać nulldo typu wartości pustych (dwie linie, jeśli nie masz istniejącej wcześniej int można ponownie wykorzystać na wyjściu TryParse):

Pre C # 7:

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

Z C # 7 w zaktualizowanym składni, który pozwala zadeklarować zmienną wyjściową w wywołaniu metody, to staje się jeszcze prostsze.

int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;
Odpowiedział 05/09/2008 o 02:14
źródło użytkownik

głosy
29

Niestety, nie mogłem się oprzeć - miał ten problem i Google przyniósł mi tutaj, ale skończyło się to (po wszystkim, jeśli i 2 zwrot : s jest soo rozwlekły!)

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

Na bardziej poważnie, staram się nie mieszać int , które jest kluczowe C #, z Int32 , która jest rodzajem Framework BCL - chociaż to działa, to po prostu sprawia, że kod wyglądać niechlujnie.

Odpowiedział 28/10/2008 o 02:26
źródło użytkownik

głosy
15

Glenn Slaven : Jestem bardziej zainteresowany wiedząc, jeśli istnieje wbudowanej metody ramy, które będą analizować bezpośrednio do wartości pustych int?

Jest to podejście, które będzie analizować bezpośrednio do int wartości pustych (i nie tylko int) jeżeli wartość jest ważna jak null lub pusty ciąg znaków, ale nie wyjątek dla nieprawidłowych wartości tak trzeba będzie złapać wyjątek i zwraca wartość domyślną dla tych sytuacjach:

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

Takie podejście może być nadal używane do non-parsowań pustych jak i pustych:

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

Uwaga: Istnieje IsValid metoda na konwerterze można użyć zamiast przechwytywania wyjątków (wyjątki rzucane powoduje zbędnego narzutu jeśli się spodziewać). Niestety to działa tylko od .NET 4, ale jest jeszcze kwestia gdzie nie sprawdza ustawienia narodowe podczas walidacji poprawne formaty DateTime, patrz bug 93559 .

Odpowiedział 25/06/2011 o 01:17
źródło użytkownik

głosy
7

Spróbuj tego:

public static int? ParseNullableInt(this string value)
{
    int intValue;
    if (int.TryParse(value, out intValue))
        return intValue;
    return null;
}
Odpowiedział 05/09/2008 o 01:27
źródło użytkownik

głosy
5

Stary temat, ale jak o:

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

Lubię to lepiej jak requriement gdzie analizować null, wersja TryParse nie rzucać błąd na przykład ToNullableInt32 (XXX). Które mogą wprowadzać niepożądane cichych błędów.

Odpowiedział 22/03/2011 o 15:17
źródło użytkownik

głosy
4

Można zapomnieć wszystkie inne odpowiedzi - jest doskonałym rozwiązaniem ogólna: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

To pozwala na pisanie bardzo czysty kod jak poniżej:

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

i również:

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();
Odpowiedział 10/11/2011 o 10:04
źródło użytkownik

głosy
3

Czuję moje rozwiązanie jest bardzo czyste i ładne rozwiązanie:

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

Jest to oczywiście rozwiązanie ogólnym wymagają jedynie, że argument rodzajowych ma statyczną metodę „Parse (String)”. To działa dla liczb, Boolean, DateTime, etc.

Odpowiedział 21/06/2011 o 12:43
źródło użytkownik

głosy
3

Poniższa powinien pracować dla każdego typu struct. Jest on oparty off kodu przez Matt Manela z forów MSDN . Jak Murph zauważa obsługi wyjątków może być drogie w porównaniu z wykorzystaniem typów dedykowane metody 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;
        }

Były to podstawowe przypadki testowe używałem.

        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);
Odpowiedział 08/04/2010 o 22:30
źródło użytkownik

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

źródła:

Odpowiedział 24/10/2018 o 13:12
źródło użytkownik

głosy
2

To rozwiązanie ma charakter ogólny, bez refleksji nad głową.

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);
}
Odpowiedział 19/11/2013 o 08:40
źródło użytkownik

głosy
1
    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;
    }
Odpowiedział 08/10/2015 o 17:32
źródło użytkownik

głosy
1

Mam wymyślić ten, który spełnił moje wymagania (chciałem moja metoda rozszerzenie naśladować możliwie blisko powrotu ram za TryParse, ale bez try {} catch {} blokach i bez kompilatora narzekających wywiedzenia pustych typu w sposób ramowy)

private static bool TryParseNullableInt(this string s, out int? result)
{
    int i;
    result = int.TryParse(s, out i) ? (int?)i : null;
    return result != null;
}
Odpowiedział 20/03/2015 o 15:01
źródło użytkownik

głosy
1

Czułem powinienem dzielić kopalni, która jest nieco bardziej ogólne.

Stosowanie:

var result = "123".ParseBy(int.Parse);

var result2 = "123".ParseBy<int>(int.TryParse);

Rozwiązanie:

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

Pierwsza wersja jest wolniejsza, ponieważ wymaga to try-catch ale wygląda czystsze. Jeśli nie zostanie wywołana wiele razy z nieprawidłowych ciągów, nie jest to takie ważne. Jeśli wydajność jest problem, należy pamiętać, że przy użyciu metody TryParse, trzeba określić parametru type ParseBy gdyż nie można wywnioskować przez kompilator. Miałem też zdefiniować jako delegata na słowo kluczowe nie mogą być stosowane w Func <>, ale przynajmniej tym razem kompilator nie wymaga wyraźnej instancji.

Wreszcie, można ją używać do innych strukturach, jak również, tj przecinku, DateTime, Guid, etc.

Odpowiedział 24/03/2011 o 14:54
źródło użytkownik

głosy
1

Znalazłem jakiś kod i dostosowane do klasy Generic NullableParser. Pełny kod znajduje się na moim blogu 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;
        }
    }
}
Odpowiedział 23/10/2009 o 14:20
źródło użytkownik

głosy
1

Jestem bardziej zainteresowany wiedząc, jeśli istnieje wbudowanej metody ramy, które będą analizować bezpośrednio do wartości pustych int?

Nie ma.

Odpowiedział 28/10/2008 o 02:31
źródło użytkownik

głosy
0

Proponuję następujące metody rozszerzenie dla parsowania ciąg do int wartości z możliwością określenia wartości domyślnej w przypadku analizowania nie jest możliwe:

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();
        }
Odpowiedział 12/03/2018 o 09:00
źródło użytkownik

głosy
0

Proponuję kodu poniżej. Możesz pracować z wyjątkiem, gdy błąd wystąpił nawrócony.

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

Użyj tej metody rozszerzenie w kodzie (wypełnić int właściwość wiekowa klasy osoba?):

string ageStr = AgeTextBox.Text;
Utils.TryParse(ageStr, i => person.Age = i, exc => { MessageBox.Show(exc.Message); });

LUB

AgeTextBox.Text.TryParse(i => person.Age = i, exc => { MessageBox.Show(exc.Message); });
Odpowiedział 10/11/2015 o 10:47
źródło użytkownik

głosy
0

Korzystanie z delegatów, następujący kod jest w stanie zapewnić ponownego użycia, jeśli znajdziesz się potrzebując zerowalne parsowania dla więcej niż jednego typu konstrukcji. Mam pokazano zarówno .Parse () i .TryParse () wersje tutaj.

To jest przykład użycia:

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

A oto kod, który dostaje się tam ...

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));
    }
  }
Odpowiedział 07/09/2009 o 22:51
źródło użytkownik

głosy
0

Należy nigdy używać wyjątek, jeśli nie trzeba - koszt jest straszne.

Wariacje na TryParse rozwiązać problem - jeśli chcesz dostać twórczy (aby Twój kod bardziej elegancki wygląd) prawdopodobnie można zrobić coś z metodę rozszerzenia w 3,5 ale kod byłby mniej więcej taki sam.

Odpowiedział 05/09/2008 o 11:58
źródło użytkownik

głosy
-1

Zdaję sobie sprawę, że jest to stary temat, ale nie może po prostu:

(Nullable<int>)int.Parse(stringVal);

?

Odpowiedział 11/03/2010 o 16:29
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more