Please add TryParse API that return nullable value for each static TryParse function
```C#
public struct Int32
{
// original
public static bool TryParse(string s, out Int32 result);
// proposed
public static Int32? TryParse(string value) => TryParse(value,out var result) ? result : (decimal?)null;
}
```
This should be added to all number struct at least
What is the benefit? What kind of problems does it solve?
Are you aiming at discoverability of the APIs? (that's the only potential reason I can come up with)
Do you have strong evidence it is a real problem? Even when taking into account that current usage pattern is well documented on MSDN, in books, and on StackOverflow and similar sites?
BTW: These questions are exactly the reason why we ask API suggestions to have formal API proposal: with motivation, examples, etc.
On technical side:
TryParse will lead to ambiguity for the compiler, because we cannot overload on return type. At minimum you need to make type part of the method name. That is getting already ugly.@karelz This is not actually a problem but it just speed things up and make life easier. We can use this to write nullable flow in parser and linq and it shorter in general
C#
var v =decimal.TryParse(value);
// vs
var v =decimal.TryParse(value,out var result) ? (decimal?)result : (decimal?)null;
// both longer, unnecessary type cast, and the result variable leaked in the function scope
But the point where it is extension method is wrong. I was copied that function from my extension method and forgot to remove it. I will fix that
ps. In my library I always write extension method TryParseInt TryParseLong TryParseDecimal for string
And so I could write int? x = "123".TryParseInt()
I still don't understand what you're proposing and why. Please post formal proposal with my questions above answered, then please update also top post. Thanks!
@karelz
```C#
public struct Int32
{
// original
public static bool TryParse(string s, out Int32 result);
// proposed
public static Int32? TryParse(string value) => TryParse(value,out var result) ? result : (decimal?)null;
}
```
What does not make you clear?
Original is what already exist in library
Proposed is what I proposing that should be added into Int8 Int16 Int32 Int64 Decimal BigInteger Float32 Float64 Float128 and maybe DateTime and DateTimeOffset
All this has API bool TryParse(string,out T) that should be easy to just add T? TryParse(string) along with. So we could write shorter code in nullable flow
What does not make you clear?
I believe you are clear as to what the API changes you want are. The problem is that it is unclear what use cases you might have that would make a compelling reason to include these changes into the core framework. Every bit of code that goes into these assemblies makes the assemblies just a little bit bigger, and everyone will have to pay the cost to load that larger assembly even if they don't use all of the APIs.
The Try... pattern is well established in the existing framework. In many of my use cases, I tend to want to know when parsing fails so that I can do something specific, and in cases where I don't care if it fails, I often end up using the default value for something like an int or decimal. The current pattern makes these use cases easy because I can either perform a TryParse inside of an if statement when I care about the result, or if I don't, I just call TryParse and ignore the result which would simply leave my integer with either the parsed value or the default of 0.
Perhaps you could explain your use cases a little more where you don't care if the parse fails and a Nullable
@gsfreema I think opposite. The Try... pattern is well established that's right. But it was the same as we make Task<> to do asynchronous in place of AsyncOperation
Nullable make all Try... method more compact. And null is the most obvious sign that the parse was failed. You can check against nullable like you use TryParse
```C#
if(!int.TryParse(s,out var v))
{
}
// vs
var v = int.TryParse(s);
if(v == null)
{
}
Is the same logic
I also have already write the common use case
```C#
var v = decimal.TryParse(value);
// vs
var v = decimal.TryParse(value,out var result) ? (decimal?)result : (decimal?)null;
// both longer, unnecessary type cast, and the result variable leaked in the function scope
Also
```C#
var v = decimal.TryParse(value) ?? -1;
// vs
var v = decimal.TryParse(value,out var r) ? r : -1;
// longer, and the r variable leaked in the function scope
//if we want to get rid of variable r we need to make 3 lines
decimal v;
if(!decimal.TryParse(value,out v))
v = -1;
//Or 2?
decimal v = -1;
v = decimal.TryParse(value,out v)) ? v : -1;
Linq is also my common use case
```C#
var availableNumbers = objects.Select((obj) => int.TryParse(obj.stringNumber)).Where((n) => n.HasValue);
Actually I write SelectNonNull extension method like this
```C#
public static int? TryParseInt(string s) => int.TryParse(s,out var i) ? (int?)i : (int?)null;
public static IEnumerable
{
foreach(var item in items)
{
var value = func(item);
if(value != null)
return value.Value;
}
}
var availableNumbers = objects.SelectNonNull((obj) => obj?.stringNumber?.TryParseInt());
```
I don't propose to get rid of the original TryParse. Because I too write if(TryParse) when I want to do logic block. But in place that I don't then nullable become handy. Especially where we want a short one line to write lambda function
Thanks, but we have no plans to move away from the Try pattern, and if we ever did, it would mean a massive overhaul to add a large number of new methods, not just one one-off.
Most helpful comment
I believe you are clear as to what the API changes you want are. The problem is that it is unclear what use cases you might have that would make a compelling reason to include these changes into the core framework. Every bit of code that goes into these assemblies makes the assemblies just a little bit bigger, and everyone will have to pay the cost to load that larger assembly even if they don't use all of the APIs.
The Try... pattern is well established in the existing framework. In many of my use cases, I tend to want to know when parsing fails so that I can do something specific, and in cases where I don't care if it fails, I often end up using the default value for something like an int or decimal. The current pattern makes these use cases easy because I can either perform a TryParse inside of an if statement when I care about the result, or if I don't, I just call TryParse and ignore the result which would simply leave my integer with either the parsed value or the default of 0.
Perhaps you could explain your use cases a little more where you don't care if the parse fails and a Nullable is more desirable than a T with a default value. And remember that even if you have a valid use case, it might not be common enough to warrant going into the framework, especially since you can handle this in your own library as a one-line piece of code.