C# switch in lambda expression

后端 未结 6 920
夕颜
夕颜 2021-02-04 04:04

Is it possible to have a switch in a lambda expression? If not, why? Resharper displays it as an error.

相关标签:
6条回答
  • 2021-02-04 04:40

    You can in a statement block lambda:

    Action<int> action = x =>
    {
      switch(x)
      {
        case 0: Console.WriteLine("0"); break;
        default: Console.WriteLine("Not 0"); break;
      }
    };
    

    But you can't do it in a "single expression lambda", so this is invalid:

    // This won't work
    Expression<Func<int, int>> action = x =>
      switch(x)
      {
        case 0: return 0;
        default: return x + 1;
      };
    

    This means you can't use switch in an expression tree (at least as generated by the C# compiler; I believe .NET 4.0 at least has support for it in the libraries).

    0 讨论(0)
  • 2021-02-04 04:43

    I checked it too :-)

    [Test]
    public void SwitchInLambda()
    {
        TakeALambda(i => {
            switch (i)
            {
                case 2:
                    return "Smurf";
                default:
                    return "Gnurf";
            }
        });
    }
    
    public void TakeALambda(Func<int, string> func)
    {
        System.Diagnostics.Debug.WriteLine(func(2));
    }
    

    Works just fine (outputs "Smurf")!

    0 讨论(0)
  • 2021-02-04 04:49

    In a pure Expression (in .NET 3.5), the closest you can get is a compound conditional:

        Expression<Func<int, string>> func = x =>
            x == 1 ? "abc" : (
            x == 2 ? "def" : (
            x == 3 ? "ghi" :
                     "jkl")); /// yes, this is ugly as sin...
    

    Not fun, especially when it gets complex. If you mean a lamda expression with a statement body (only for use with LINQ-to-Objects), then anything is legal inside the braces:

        Func<int, string> func = x => {
            switch (x){
                case 1:  return "abc";
                case 2:  return "def";
                case 3:  return "ghi";
                default: return "jkl";
            }
        };
    

    Of course, you might be able to outsource the work; for example, LINQ-to-SQL allows you to map a scalar UDF (at the database) to a method on the data-context (that isn't actually used) - for example:

    var qry = from cust in ctx.Customers
              select new {cust.Name, CustomerType = ctx.MapType(cust.TypeFlag) };
    

    where MapType is a UDF that does the work at the db server.

    0 讨论(0)
  • 2021-02-04 04:58

    Hmm, I see no reason why this shouldn't work. Just be careful with the syntax you use

    param => {
        // Nearly any code!
    }
    
    delegate (param) {
        // Nearly any code!
    }
    
    param => JustASingleExpression (No switches)
    
    0 讨论(0)
  • 2021-02-04 05:02

    Yes, it works, but you have to put your code in a block. Example:

    private bool DoSomething(Func<string, bool> callback)
    {
        return callback("FOO");
    }
    

    Then, to call it:

    DoSomething(val =>
                    {
                        switch (val)
                        {
                            case "Foo":
                                return true;
    
                            default:
                                return false;
                        }
                    });
    
    0 讨论(0)
  • 2021-02-04 05:06

    I just learn this:

                          (model) =>
                                    {
                                        switch(model.SentInvoiceTypeId)
                                        {
                                            case 1:
                                                return "1 asdf";
                                            case 2:
                                                return "2 asdf";
                                            case 3:
                                                return "3 asdf ";
                                            case 4:
                                                return "4 asdf ";
                                            default:
                                                return "asdf";
                                        }
                                    }
    

    Just put between the "model" () and add your code in { }, remember to have a return.
    I am not sure in which versions of C# will work, In this example is the C# 7.0

    I hope this answer can help someone.

    0 讨论(0)
提交回复
热议问题