I suggest you ...

Let lambdas with a statement body be converted to an expression tree

The C# compiler supports translating a lambda expression to an expression tree (System.Linq.Expressions).

Today lambdas with no statement body (only a single statement) are supported just fine.

Expression<Action> x = () => Console.WriteLine("Hello World");

But lambdas with a statement body (braces), which is needed to have multiple statements, doesn't compile.

Expression<Action> y = () => { Console.WriteLine("Hello"); Console.WriteLine("World"); };

I believe there is a lot of awesome stuff not being possible due to this lack of support.

It seems very unproblematic to implement, but if there are any hidden issues with this feature, it would be nice to know so I can forget it.

372 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    scavic shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    7 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      Signed in as (Sign out)
      Submitting...
      • Thomas commented  ·   ·  Flag as inappropriate

        @Donald Record, in my case, as @Daniil Rodin said, shaders. I be nice to write shaders in c# (as the meta language) then translate them to api specific code. That would all be lost building the tree with the expression api.

      • Matt Ritchie commented  ·   ·  Flag as inappropriate

        This code works in .net 4 and VS203
        Inside a StructureMap Registry
        For<ILog>()
        .AlwaysUnique()
        .Use(s =>
        {
        var logger = LogManager.GetLogger(s.ParentType ?? s.BuildStack.Current.ConcreteType);
        LogManager.GetRepository().LevelMap.Add(LogExtensions.AlwaysLogLevel);

        return logger;
        });

        Code Still works in VS2017, but when upgrading to .net 4.5.2 through a class library (netstandard and netframe) it doesn't compile.

        I've worked around like this

        For<ILog>().Use(s=> RunANewMethod<ILog>(s)).AlwaysUnique();

        private T RunANewMethod<T>(IContext context) where T:ILog
        {
        var logger = LogManager.GetLogger(context.ParentType?? context.RootType);
        LogManager.GetRepository().LevelMap.Add(LogExtensions.AlwaysLogLevel);
        return (T)logger;
        }

      • Daniil Rodin commented  ·   ·  Flag as inappropriate

        To write shaders in C# as a block-expression and automaticly compile them to HLSL/GLSL...
        To write client code for a web application in C# as a block-expression and automaticly compile it to JavaScript...
        Yes, please!

      • Maxipes Fik commented  ·   ·  Flag as inappropriate

        Why for the heaven goodness is this still not implemented ;-(?.. One can not design a dynamic predicate builder with complexer logic without this :-(!!! This enforces unneeded runtime overhead and suboptimal architecture.. Thank you

      • --- commented  ·   ·  Flag as inappropriate

        Because they already have extended the LINQ Expression trees to statements for the purpose of the Dynamic Language Runtime (DLR), it should not be a problem to model it program-wise.

        The only real problem i can come up with is that LINQ Query Providers like LINQ-to-SQL (or, more likely, 3rd-party query providers) might not be prepared to deal with statements
        instead of expressions only. Thus, this might cause some unexpected exceptions and/or misbehavior at runtime, when a query provider encounters expressions it does not know how to handle.

      • Sean McCarthy commented  ·   ·  Flag as inappropriate

        This would be grand - tons of use cases open up. For one, we could easily implement monad like functionality and build stored procedures from them.

      Feedback and Knowledge Base