开发者

int.TryParse syntatic sugar

int.TryPrase is great and all, but there is only one problem...it takes at least two lines of code to use:

int intValue;
string str开发者_如何学编程ingValue = "123";
int.TryParse(stringValue, out intValue);
....

Of course I can do something like:

string stringValue = "123";
int intValue = Convert.ToInt32(string.IsNullOrWhiteSpace(stringValue) ? 0 : stringValue); 

on just one line of code.

How can I perform some magic to get int.TryParse to use a one liner, or is there yet a third alternative out there?

Thanks!

Bezden answered the question best, but in reality I plan on using Reddogs solution.


int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0;


Maybe use an extension method:

public static class StringExtensions
{
    public static int TryParse(this string input, int valueIfNotConverted)
    {
        int value;
        if (Int32.TryParse(input, out value))
        {
            return value;
        }
        return valueIfNotConverted;
    }
}

And usage:

string x = "1234";
int value = x.TryParse(0);

Edit: And of course you can add the obvious overload that already sets the default value to zero if that is your wish.


This answer is only for those who use at least C# 7.

You can now declare the out parameter inline.

int.TryParse("123", out var result);

Exemplary usage:

if (int.TryParse("123", out var result)) {
    //do something with the successfully parsed integer
    Console.WriteLine(result);
} else {
    Console.WriteLine("That wasn't an integer!");
}

MSDN: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#out-variables


I would create an extension method out of this.

public static int? AsInt32(this string s)
{
    int value;
    if (int.TryParse(s, out value))
        return value;

    return null;
}


I don't think there is anything really beautiful, but if you like this you get it down to one row:

string stringValue = "123"
int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0;


Check out the StringExtensions class. It contains an AsInt(String,Int32) extension method that will attempt to convert a string and if unsuccessful populate it with the supplied Int32 value as default.

Example:

var intValue = "123".AsInt(-1);


int val2 = "asd".AsInt(-1); 
//Output : -1
 int val3 = "123".AsInt(-1); 
//Output : 123

You need to have System.Web.WebPages namespace.


One last addition to this NINE year-old question :). Bool parsing is a little different because if parsing fails, you don't want to return a default value, you want to return a NULL. This line does this (as of C# 7, I think):

return bool.TryParse(value, out bool result) ? (bool?)result : null;

That cast of the result is necessary, otherwise it cannot reconcile the differing types of the two return values.


In C# 7.0+ you can use inline variable declaration.

  • If parse successes - intValue = its parsed value.
  • If parse fails - intValue = 0.

Code:

int.TryParse(stringValue, out int intValue);

Drawback:

You cannot differentiate between a 0 value and a non parsed value.


You do not WANT to make int.TryParse() one line. Why? Because you can't make an assignment to intValue if the input string isn't a valid integer. The whole point of TryParse() is to allow you to test for good input and degrade gracefully, rather than having to catch an exception.

Int.TryParse() is already a shortcut so you don't have to test for a valid int and do the assignment in two steps... that's as far as you want to take it.


Because it essentially returns two values (success and the value), we really do need the two lines.

You could try a wrapper class, ie:

void Main()
{
    var result = simpleIntParser.TryParse("1");
    if(result)
    {
        Console.WriteLine((int)result);
    } else {
        Console.WriteLine("Failed");
    }

    result = simpleIntParser.TryParse("a");
    if(result)
    {
        Console.WriteLine((int)result);
    } else {
        Console.WriteLine("Failed");
    }


}

public class simpleIntParser
{
    public bool result {get; private set;}
    public int value {get; private set;}

    private simpleIntParser(bool result, int value)
    {
        this.result = result;
        this.value = value;
    }

    public static simpleIntParser TryParse(String strValue)
    {
        int value;
        var result = int.TryParse(strValue, out value);
        return new simpleIntParser(result, value);
    }

    public static implicit operator int(simpleIntParser m)
    {
        return m.value;
    }

    public static implicit operator bool(simpleIntParser m)
    {
        return m.result;
    }
}

It requires casting if the type is ambiguous (i.e. for Console.WriteLine()), but if you pass it as an integer parameter for example, no casting is required


This technically isn't the most efficient as it parses the string twice, but it does get it into one line.
Result as Nullable<int>:

int? ToInt(string value) => int.TryParse(value, out _) ? int.Parse(value) : (int?)null;
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜