views:

112

answers:

4

I needed a one-liner to convert a string to an integer, and if the string is anything invalid, then just set it to zero. So I made the following extension method, but I can imagine there is a system method to do this in one line.

Is there another way to do this in one line without creating an extension method?

using System;

namespace TestForceInteger
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("testing".ForceInteger() + 1);
            Console.WriteLine("199".ForceInteger() + 1);
            int test = StringHelpers.ForceInteger(null);
            Console.WriteLine(test + 1);
            Console.ReadLine();
            //output:
            //1
            //200
            //1
        }
    }

    public static class StringHelpers
    {
        public static int ForceInteger(this string potentialInteger)
        {
            int result;
            if (int.TryParse(potentialInteger, out result))
                return result;
            else
                return 0;
        }
    }
}
+3  A: 

Not as a one-liner, afaik, but if you want to avoid the extension method you can initialize the result to 0 and ignore the outcome of TryParse:

int result = 0;
int.TryParse(potentialInteger, out result)
Paolo Tedesco
That will work in this case, because `TryParse` will set it to 0 if the string is invalid, but is generally risky. `TryParse` *has* to set `result` to some value (that's how `out` parameters work), so the value you preassign to it is absolutely meaningless.
mquander
This might not work. There's no guarantee that `result` will be 0 if the parsing fails.
Gabe
@Gabe: If you look at the implementation of `TryParse` in the framework, you'll see that it will indeed set it to 0 every time if the parsing fails.
mquander
@Gabe, no, it will be 0 on a failed conversion according to the method's documentation. http://msdn.microsoft.com/en-us/library/f02979c7(v=VS.100).aspx
Anthony Pegram
Anthony: I see, you're right. I was looking at the docs, but was looking for "0" instead of "zero" so I didn't see it.
Gabe
mquander: I did look at the source, but you can't rely on looking at the source code and expect it to stay that way. It turns out that it *is* documented, so I was wrong.
Gabe
@mquander: you are right, the initialization does not grant anything.
Paolo Tedesco
+2  A: 

Not a conventional way with the framework libraries, no.

Your extension method would be better if it returned a nullable int, so that you could distinguish between "invalid" and 0.

mquander
I think the whole point of the method is that he wants invalid to be zero.
DeadMG
+1 for the distinction between an invalid input and 0.
Anthony Pegram
@DeadMG: I would argue that it's a lousy method, then. If he wants invalid things to take on zero, he ought to write `Parse(str) ?? 0`. It's just not idiomatic C# to have a method that return a magic sentinel value indicating "invalid" -- it's better to use nulls, tuples, or throw exceptions.
mquander
These klugey methods do have quite a lot of application when needing to deal fault tolerantly with poor data quality or legacy systems, e.g. from a db storing ints in strings (U2 anyone?) and working with XML docs from other systems etc
nonnb
It's not a magic value. He doesn't care about invalid. He just wants zero instead. He doesn't want to distinguish. You don't understand the point of the method.
DeadMG
A: 

Don't code for simplicity of writing your code, code to the specification. It makes far more sense to create a method that actually does the job properly and notes the difference between an invalid conversion and a magic number. When you make this method, you need only make it once, so do it properly. In the layer above it you can then do the conversion you require to whatever system you are using.

I.e.:

public static class Extensions
{
    public static int? ReturnIntegerIfValid(this string potentialInteger)
    {
        try
        {
            int result;

            if (int.TryParse(potentialInteger, out result))
            {
                return result;
            }
            else
            {
                return null;
            }
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}
Kyle Rozendo
A: 

Use

int result;
result = Int32.TryParse(potentialInteger, out result) ? result : 0; // or default(int)

to ensure setting to 0. But this is absolutely unnecessary (see @Anthony's comment to @Paolo's answer)

abatishchev