Execute lambda expression immediately after its definition?

后端 未结 5 1842
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-03 17:56

Is there a way to execute a lambda expression immediately after its definition?

In other words (Invalid C# code):



        
相关标签:
5条回答
  • 2021-01-03 18:25

    Here's an example of how this might be used. You want to initialize a constructor with the result of a few lines of code that can't be written as a function because that is how the 3rd party API is structured.

    It is just glue code to prevent writing a standalone function that is never called anywhere else. I'm using Func instead of Action, but the answer is the same as user166390.

            // imagine several dozens of lines that look like this
            // where the result is the return value of a function call
            fields.Add(new ProbeField(){ 
                Command = "A",
                Field = "Average",
                Value = be.GetAverage()
            });
    
            // now you need something that can't be expressed as function call
            // so you wrap it in a lambda and immediately call it.
            fields.Add(new ProbeField(){ 
                Command = "C",
                Field = "Cal Coeff",
                Value = ((Func<string>)(() => {
                    CalCoef coef;
                    Param param;
                    be.GetCalibrationCoefficients(out coef, out param);
                    return coef.lowDet1.ToString();
                }))()
            });
    
    0 讨论(0)
  • 2021-01-03 18:31

    For my own projects I've sometimes written a tiny reusable helper function to make the syntax for an immediately invoked lambda look shorter. This 'Inv' was inspired by the similar 'fun' function in the LanguageExt library.

    // Helper utility functions
    public static void Inv(Action a) => a();
    public static T Inv<T>(Func<T> f) => f();
    
    private static void TestMethod()
    {
        // Action example
        Inv(() => Console.WriteLine("Hello World!"));
        // Func example with no parameters
        bool result = Inv(() =>
        {
            if (1 == 1)
                return true;
            else
                return false;
        });
    }
    

    You could also extend this with a few other overloads to make it so you could pass in parameters, but these look a bit more cumbersome syntax wise and may not be as helpful.

    public static Func<A, T> Inv<A, T>(Func<A, T> f) => f;
    public static Func<A, B, T> Inv<A, B, T>(Func<A, B, T> f) => f;
    
    string printNumber = Inv((int number) => $"This is the number {number}")(5);
    int addedNumbers = Inv((int x, int y) => x + y)(5, 6);
    
    0 讨论(0)
  • 2021-01-03 18:44

    You should be able to do this:

    Action runMe = () => { Console.WriteLine("Hello World"); };
    runMe();
    
    0 讨论(0)
  • 2021-01-03 18:51

    Sure.

    new Action(() => { Console.WriteLine("Hello World"); })();
    

    That should do the trick.

    0 讨论(0)
  • 2021-01-03 18:52

    Another "option", which is just the other two answers in a slightly different guise:

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

    The reason, as directly taken from phoog's comment:

    ...you haven't told the compiler whether you want an Action or an Expression<Action>. If you cast that lambda expression to Action, you'll be able to call Invoke on it or use the method-call syntax () to invoke it.

    It sure gets ugly though, and I do not know of a place where this form is ever useful, as it cannot be used for recursion without a name...

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