2014-11-04 105 views
7

有没有什么办法在C#中创建一个变量内联? 事情是这样的:TryParse创建内嵌参数?

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

难道你不认为这是比外面创建变量更加有用,然后不会再使用它?

+0

可以包装它在一个私有方法调用? – 2014-11-04 13:56:35

+0

我该怎么做? – 2014-11-04 14:00:32

回答

12

该语法 - 称为声明表达式 - 位于下一版C#(版本6)的建议功能列表中。

你不是唯一认为它有用的人。例如,使一个完整的TryParse调用一个表达式(不需要声明来声明该变量)。

然而它从has been dropped正在进行的工作到C#6。

我确定我不是唯一一个希望在未来的版本中能够获得回报的人。它包括在C#7作为申报(无需new):

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

我明白了为什么现在放弃它 - 虽然需要太多特殊情况或handwavey解析来支持它。 – 2014-11-04 14:06:56

+0

@MatthewWatson更多的情况下,看到F#的模式匹配,并希望做更接近的事情,解决这个(我希望),因此成为C#7的一部分。 – Richard 2015-06-12 16:54:52

0

基于OP要求:

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

就算不是最聪明不过的方法,最简单的我猜: )也可以用扩展方法来包装这个。

+0

这有点棘手的方式,但感谢解释。 – 2014-11-04 14:29:57

4

out paraline的内联声明是C#中的一项新建议功能,可能是标准的一天,请参阅参考资料。 Probable C# 6.0 features illustrated,部9。预期/建议的语法:

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

编辑: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 -parameter:

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

棘手的方式来解决问题。 – 2014-11-04 14:19:05

+0

但是如果我想让这个更通用?我的意思是'Guid.TryParse'和'TimeSpan.TryParse'等。我在我的答案中尝试了一个通用扩展。 – 2014-11-04 14:25:24

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

很有意思,但这是否有效? – 2014-11-10 10:50:39

+0

我不明白为什么这应该是低效的。没有对象被创建,只有一个泛型被使用后才被构建。 – IllidanS4 2014-11-10 16:09:16