开发者

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 = In开发者_运维技巧t32.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?


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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜