122

I am trying to use TryParse to find if the string value is an integer. If the value is an integer then skip foreach loop. Here is my code.

string strValue = "42 "

 if (int.TryParse(trim(strValue) , intVal)) == false
 {
    break;
 }

intVal is a variable of type int?(nullable INT). How can I use Tryparse with nullable int?

0

5 Answers 5

177

Here's an option for a nullable int with TryParse

public int? TryParseNullable(string val)
{
    int outValue;
    return int.TryParse(val, out outValue) ? (int?)outValue : null;
}
Sign up to request clarification or add additional context in comments.

8 Comments

I like this version since "0" returns 0 and "hello" returns null. In the accepted answer, the distinction is lost.
I don't like his answer because it loses the return value indicating the success/failure of the parse. That's an important feature of a Try* method.
@frattaro I don't really see why this answer could be bad. Try parse returns 0 by default on failure, in this sample it just returns null instead.
With C#7 it's even easier, no need to have a function, one line is enough : int? myVal = int.TryParse(toCheck, out int tmp) ? (int?)tmp : null;
@frattaro this has an indicator that the parse failed - null.
|
89

You can't do this without using another variable, unfortunately - because the type of out arguments has to match the parameter exactly.

Like Daniel's code, but fixed in terms of the second argument, trimming, and avoiding comparisons with Boolean constants:

int tmp;
if (!int.TryParse(strValue.Trim(), out tmp))
{
    break;
}
intVal = tmp;

6 Comments

@JonSkeet - strValue cna be null and the Trim() method would result in an exception. Just saying. :)
@ShaktiPrakashSingh: We don't know whether strValue could be null or not. If it's coming from a text box, it probably can't be null. My code doesn't try to address this, but we really don't know whether or not it should address it.
why not reverse the if? e.g: if (int.TryParse(Request["idParent"], out tmp)) idParent = tmp; (otherwise its null)
@JonSkeet it's worth noting, I think, that while your code matches exactly what the questioner asks (since it's about a loop/break condition most likely), if someone tries to naively adapt this in a non-loop scenario they will end up with 0 as intVal rather than null in the case that strValue can't be parsed as an int. Of course, you should never copy/paste from the internet just because an answer is accepted ^_^.
With c#7 it's one line : int? myVal = int.TryParse(toCheck, out int tmp) ? (int?)tmp : null;
|
26

Could not prevent myself to produce a generic version. Usage below.

    public class NullableHelper
    {
        public delegate bool TryDelegate<T>(string s, out T result);

        public static bool TryParseNullable<T>(string s, out T? result, TryDelegate<T> tryDelegate) where T : struct
        {
            if (s == null)
            {
                result = null;
                return true;
            }

            T temp;
            bool success = tryDelegate(s, out temp);
            result = temp;
            return success;
        }

        public static T? ParseNullable<T>(string s, TryDelegate<T> tryDelegate) where T : struct
        {
            if (s == null)
            {
                return null;
            }

            T temp;
            return tryDelegate(s, out temp)
                       ? (T?)temp
                       : null;
        } 
    }


bool? answer = NullableHelper.ParseNullable<bool>(answerAsString, Boolean.TryParse);

Comments

6

You can create a helper method to parse a nullable value.

Example Usage:

int? intVal;
if( !NullableInt.TryParse( "42", out intVal ) )
{
    break;
}

Helper Method:

public static class NullableInt
{
    public static bool TryParse( string text, out int? outValue )
    {
        int parsedValue;
        bool success = int.TryParse( text, out parsedValue );
        outValue = success ? (int?)parsedValue : null;
        return success;
    }
}

Comments

6

You could also make an extension method for this purpose;

public static bool TryParse(this object value, out int? parsed)
{
    parsed = null;
    try
    {
        if (value == null)
            return true;

        int parsedValue;
        parsed = int.TryParse(value.ToString(), out parsedValue) ? (int?)parsedValue : null;
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

I've made this an extension on the object type, but it could equally well be on string. Personally I like these parser-extensions to be available on any object hence the extension on object instead of string.

Example of use:

[TestCase("1", 1)]
[TestCase("0", 0)]
[TestCase("-1", -1)]
[TestCase("2147483647", int.MaxValue)]
[TestCase("2147483648", null)]
[TestCase("-2147483648", int.MinValue)]
[TestCase("-2147483649", null)]
[TestCase("1.2", null)]
[TestCase("1 1", null)]
[TestCase("", null)]
[TestCase(null, null)]
[TestCase("not an int value", null)]
public void Should_parse_input_as_nullable_int(object input, int? expectedResult)
{
    int? parsedValue;

    bool parsingWasSuccessfull = input.TryParse(out parsedValue);

    Assert.That(parsingWasSuccessfull);
    Assert.That(parsedValue, Is.EqualTo(expectedResult));
}

The downside would be that this breaks with the frameworks syntax for parsing values;

int.TryParse(input, out output))

But I like the shorter version of it (whether it's more readable or not might be subject to discussion);

input.TryParse(out output)

3 Comments

If you do this, you're locked into TryParse for int only. What about double? Or bool?
@FMM a bit late but, write a separate extension method for those if you want them. not sure what you mean "locked in" the other extension methods would have a different signature
T is implicitly convertible to T? for structs. This is overkill.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.