2014-11-04 6 views
7

Есть ли способ в C# создать переменную inline? Что-то вроде этого:TryParse создать встроенный параметр?

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

Разве вы не думаете, что это более полезно, чем создавать переменную снаружи и затем никогда не использовать его снова?

+0

Можно обернуть его в частном вызове метода? –

+0

как я могу это сделать? –

ответ

12

Этот синтаксис - выражение - был включен в список предлагаемых функций для следующей версии C# (версия 6).

Вы не единственный, кто считает его полезным. Например, создание полного TryParse вызывает выражение (нет необходимости в заявлении для объявления переменной).

Однако это has been dropped от текущей работы до C# 6.

Я уверен, что я не единственный, кто надеется, что он вернется в будущую версию. Он включен в C# 7 в качестве декларации (нет необходимости new):

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

Я могу понять, почему они бросили это сейчас, хотя слишком много специальных случаев или ручного разбора, необходимых для его поддержки. –

+0

@MatthewWatson Еще один случай, когда вы видите соответствие F # и хотите сделать что-то ближе к этому, решив это, я надеюсь, что это станет частью C# 7. – Richard

0

По желанию OP:

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

возмещаться не самый умный подход, однако, самый простой, я не думаю,:) Может также обернуть это методом расширения.

+0

Это немного сложно, но спасибо за объяснение. –

4

Встроенные объявления для out params - это новая предлагаемая функция на C#, которая может быть стандартной в один день, см., Например, Probable C# 6.0 features illustrated, раздел 9. Ожидаемый/предложенный синтаксис:

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

Edit: Эта переменная out синтаксис был в конечном счете включен в C# 7.0 (Visual Studio 2017); вы также можете использовать out var x.


Дополнение: Люди придумывают интересные методы расширения. Я попытался сделать один общий:

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

Это может быть использовано, как это:

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

и так далее. Я надеялся, что компилятор будет выводить T от использования, так что можно было бы просто сказать:

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

, но в этом случае вы должны явно указать тип аргумента метода.

3

В качестве временного решения можно создать расширение:

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

Тогда вам не нужно даже в out -параметрической:

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

сложный способ решить проблему. –

+0

Но что, если я хочу сделать это более общим? Я имею в виду 'Guid.TryParse' и' TimeSpan.TryParse' и т. Д. Я пробовал обобщенное расширение в своем ответе. –

0

Вы можете также использовать временное хранилище для всех методов.

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

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

Очень интересно, но эффективен ли это? –

+0

Я не понимаю, почему это должно быть неэффективным. Объекты не создаются, после его создания создается только общий тип. – IllidanS4

Смежные вопросы