如何将临时变量声明为C#表达式?

时间:2019-01-14 10:11:42

标签: c# expression

是否可以在表达式中声明临时变量以重用中间结果?

的动机是,当您需要在逻辑或转换中多次使用计算结果时,仍然能够使用流利的样式调用链和表达式合并方法。

public static string Foo(IBar bar)
{
    var result = bar.LongCalculation();

    return result.HasError
        ? throw new Exception()
        : result.ToString();
}

我认为我也许可以使用let / select linq查询关键字,但是如果没有from子句,这似乎是不可能的。

public static string Foo(IBar bar) =>
    let result = bar.LongCalculation()                
    select result.HasError
        ? new Exception()
        : result.ToString();

3 个答案:

答案 0 :(得分:3)

您可以使用扩展方法:

public static class LongCalculationExtensions
{
    public static ILongCalculationResult ThrowIfHasError(this ILongCalculationResult result)
    {
       if(result.HasError) throw new Exception("Your exception here");

       return result;
    }
}

然后您可以像这样使用它:

public static string Foo(IBar bar) => bar.LongCalculation().ThrowIfHasError().ToString();   

答案 1 :(得分:0)

我首选的方法是蒂莫西·希尔兹(Timothy Shields)在这里回答:

How to "let" in lambda expression?

创建类似于F#的管道运算符的扩展方法:

public static class FunctionalExtensions
{
    public static TResult Pipe<T, TResult>(this T value, Func<T, TResult> func) =>
        func(value);
}

并这样称呼

public static string Foo(IBar bar) =>
    bar.LongCalculation()
       .Pipe(result => result.HasError
           ? throw new Exception()
           : result.ToString();

答案 2 :(得分:0)

我以前对Pipe的回答需要一个lambda,而开销较小的更好解决方案是利用内联输出声明:

public static class FunctionalExtensions
{
    public static T Assign<T>(this T o, out T result) =>
        result = o;
}

并这样称呼

public static string Foo(IBar bar) =>
    bar.LongCalculation()
       .Assign(out var result)
       .HasError
           ? throw new Exception()
           : result.ToString();