Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any problem declaring a variable and using TryParse to initialize it on same line?

This example is in C# but I expect could apply to others just as easily.

I recently found that the following seems to work just fine:

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Somehow it seems as though the variable i shouldn't technically be accessible at the point it appears in TryParse. Or would I be correct to assume that int i effectively declares the variable, even though there is no end of statement yet?

like image 683
JYelton Avatar asked Dec 30 '10 20:12

JYelton


People also ask

What is the use of TryParse command in VC?

TryParse(ReadOnlySpan<Char>, Int32)Converts the span representation of a number in a specified style and culture-specific format to its 32-bit signed integer equivalent. A return value indicates whether the conversion succeeded.

What is difference between Parse and TryParse?

The Parse method returns the converted number; the TryParse method returns a boolean value that indicates whether the conversion succeeded, and returns the converted number in an out parameter. If the string isn't in a valid format, Parse throws an exception, but TryParse returns false .

What method parameter type is used by TryParse method?

The type of this parameter is System. Char.

Can you TryParse a string?

TryParse(String, Single) Converts the string representation of a number to its single-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.


3 Answers

int i declares the variable, and using it in the out parameter initializes it. Since the predicate must be evaluated before the consequent, i is therefore both declared and initialized before use. (out parameters must be assigned before returning, so it is definitely initialized in any case.)

That said, there are colleagues of mine that would throw a fit at seeing something like that on style grounds. :-)

EDIT: After surveying how this has shaken out, I'll propose a couple of possible alternative helper methods. Naming of the static class acts as intention documentation for the helper methods here.

internal static class TryConvert
{
    /// <summary>
    /// Returns the integer result of parsing a string, or null.
    /// </summary>
    internal static int? ToNullableInt32(string toParse)
    {
        int result;
        if (Int32.TryParse(toParse, out result)) return result;
        return null;
    }

    /// <summary>
    /// Returns the integer result of parsing a string,
    /// or the supplied failure value if the parse fails.
    /// </summary>
    internal static int ToInt32(string toParse, int toReturnOnFailure)
    {
        // The nullable-result method sets up for a coalesce operator.
        return ToNullableInt32(toParse) ?? toReturnOnFailure;
    }
}

internal static class CallingCode
{
    internal static void Example(string someString)
    {
        // Name your poison. :-)
        int i = TryConvert.ToInt32(someString, -1);
        int j = TryConvert.ToNullableInt32(someString) ?? -1;

        // This avoids the issue of a sentinel value.
        int? k = TryConvert.ToNullableInt32(someString);
        if (k.HasValue)
        {
            // do something
        }
    }
}
like image 120
Jeffrey Hantin Avatar answered Oct 24 '22 19:10

Jeffrey Hantin


I recently found that the following seems to work just fine

 int i = Int32.TryParse(SomeString, out i) ? i : -1;

It works, but it is not fine.

Any problem declaring a variable and using TryParse to initialize it on same line?

Yes, readability. I think this looks awful, and it is doing double work.


Part of your problem is that you want -1 as your default. Int32.TryParse explicitly defines 0 as the out value when conversion fails.

I would still break it up in 2 lines for readability's sake.

int i;
if (! int.TryParse(SomeString, out i))  i = -1;

And when you need this a lot, write a (static but not extension) helper method:

int i = Utils.ParseInt(SomeString, -1);
like image 33
Henk Holterman Avatar answered Oct 24 '22 18:10

Henk Holterman


Remember that there is no ternary operator in CIL.

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Your code is transformed into CIL representing the following C# code:

int i;
if (Int32.TryParse(SomeString, out i))
  i = i;
else
  i = -1;

Which is perfectly fine.

like image 33
jakobbotsch Avatar answered Oct 24 '22 18:10

jakobbotsch