1

I am working on an application where we need to log entire statement of anonymous (lambda) function.

What it means is that the "LogAction" method should log all the statements that are passed as action.

        protected void LogAction(Action action)
        {
            /*
                Log the statement(s) passed to this method i.e. should print
                    var a = 10;
                    var b = 20;
                    Console.WriteLine($"Sum  of {a} and {b} is {a+b}");
            */
        }
        LogAction(() =>
        {
            var a = 10;
            var b = 20;
            Console.WriteLine($"Sum  of {a} and {b} is {a+b}");
        });
user2107373
  • 427
  • 3
  • 16
  • 1
    That exposes Application Logic to the outside. Not the best of ideas. Is this for debugging purposes? – Fildor Mar 02 '21 at 07:18
  • yes, only for debugging purpose. – user2107373 Mar 02 '21 at 07:21
  • Well, for one you can step into that code, so I personally wouldn't want to write the code to log. Also, you could make that `Action` and log from inside the Action (and only what's actually helpful in debugging). – Fildor Mar 02 '21 at 07:26
  • 1
    On a second thought: If those are anonymous and you do have recurring problems with them, why not make them _not_ anonymous and write unit-tests? – Fildor Mar 02 '21 at 07:27
  • 1
    Consider that the compiler might very well optimize your example to `Console.WriteLine($"Sum of 10 and 20 is 30");`. – JonasH Mar 02 '21 at 07:31
  • 1
    ^^ And it might do so differently in Debug and Release. – Fildor Mar 02 '21 at 07:31
  • I am actually building a code generator that would generate C# code. I have two options, either write each statement as a string in the output C# file (error prone) or using anonymous blocks like I shared above, which will highlight any compilation error and finally output its content to the file. – user2107373 Mar 02 '21 at 10:55

1 Answers1

0

You can use the Expression class in C#:

Expression<Action> ex = () => System.Console.WriteLine("Hello world");

Console.WriteLine(ex.ToString());

The above code will print () => WriteLine("Hello world") on the console. This should help enough for debugging purposes. Unfortunately it does not provide as much flexibility as one would expect. For example the following initialization will give you an error:

//ERROR: A lambda expression with a statement body cannot be converted to an expression tree
Expression<Action> ex = () => 
            {
                int a = 10;
                int b = 21;
                Console.WriteLine(a + b);
            };

A way around this is to define a method which you can later on assign to the Expression object:

void Sum()
        {
            int a = 10;
            int b = 21;
            Console.WriteLine(a + b);
        }

Valid assignment:

Expression<Action> ex = () => Sum();
Console.WriteLine(ex.ToString());

The above code prints () => Sum() on the console.

dimitar.d
  • 645
  • 1
  • 6
  • 18