25

Is there any way in C# to create a variable inline? Something like this:

int x = int.TryParse("5", out new int intOutParameter) ? intOutParameter : 0;

Don´t you think that this is more useful than creating a variable outside and then never use it again?

1
  • Can wrap it in a private method call? Commented Nov 4, 2014 at 13:56

5 Answers 5

32

That syntax – called declaration expressions – was on the proposed feature list for the next version of C# (version 6).

You're not the only one to think it is useful. For instance making a complete TryParse call an expression (no need for a statement to declare the variable).

However it has been dropped from the ongoing work to C#6.

I'm sure I'm not the only one hoping it will make a return in a future version.It is included in C#7 as a declaration (no need for new):

int x = int.TryParse("5", out int intOutParameter) ? intOutParameter : 0;
Sign up to request clarification or add additional context in comments.

2 Comments

I can see why they dropped it for now though - too many special cases or handwavey parsing needed to support it.
@MatthewWatson More a case of seeing F#'s pattern matching and wanting to do something closer to that, solving this will (I hope) thus become part of C# 7.
12

Inline declarations for out params is a new suggested feature in C# that might be standard one day, see e.g. Probable C# 6.0 features illustrated, section 9. The expected/proposed syntax:

int.TryParse("5", out int x); // this declares (and assigns) a new variable x

Edit: This out variable syntax was eventually included in C# 7.0 (Visual Studio 2017); you can also use out var x.


Addition: People come up with fun extension methods. I tried to make a generic one:

public delegate bool TryParser<TResult>(string s, out TResult result);

public static class FunExtensions
{
  public static T TryParse<T>(this string str, TryParser<T> tryParser)
  {
    T outResult;
    tryParser(str, out outResult);
    return outResult;
  }
}

This can be used like this:

  var x = "5".TryParse<int>(int.TryParse);
  var y = "01/01".TryParse<DateTime>(DateTime.TryParse);
  var z = "bad".TryParse<decimal>(decimal.TryParse);

and so on. I was hoping the compiler would infer T from usage, so that one could say simply:

  var x = "5".TryParse(int.TryParse);  // won't compile

but it appears you have to explicitly specify the type argument to the method.

Comments

3

As a workaround you could create an extension:

public static int TryParse(this string input, int defaultValue = default(int))
{ 
    int intOutParameter;
    bool parsable = int.TryParse(input, out intOutParameter);
    if (parsable)
        return intOutParameter;
    else
        return defaultValue;
}

Then you don't even need an out-parameter:

int parsed = "5".TryParse(0);

1 Comment

But what if I want to make that more generic? I mean Guid.TryParse and TimeSpan.TryParse etc. I tried a generic extension in my answer.
0

Based on OP request:

private static bool IsIntValid(string str)
{
  int i = 0;
  return int.TryParse(str, out i);
}

Granted not the most cleverest approach however, the simplest I guess :) Can wrap this in an extension method also perhaps.

Comments

0

You can also use a temporary storage for all methods.

public static class Tmp<T>
{
    [ThreadStatic]
    public static T Value;
}

 

int x = int.TryParse("5", out Tmp<int>.Value) ? Tmp<int>.Value : 0;

2 Comments

very interesting, but is this efficient?
I don't see why this should be inefficient. No objects are created, only a generic type is built once it is used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.