如何创建一个接受lambda表达式作为参数的方法?

时间:2010-03-06 18:25:29

标签: .net c#-3.0 lambda

我使用以下代码将属性传递给lambda表达式。

namespace FuncTest
{
    class Test
    {
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test t = new Test();
            t.Name = "My Test";
            PrintPropValue(t => t.Name);

        }

        private static void PrintPropValue(Func<string> func)
        {
            Console.WriteLine(func.Invoke());
        }

    }
}

这不编译。我只是希望函数能够获取属性并能够进行评估。

2 个答案:

答案 0 :(得分:8)

Func<string>没有任何参数 - 但是你的lambda表达式确实如此。

目前尚不清楚是否想要Func<Test, string> - 在这种情况下,您需要在调用委托时传递Test的实例 - 或者是否你想要一个Func<string>来捕获一个特定的Test实例。对于后者:

using System;

class Test
{
    public string Name { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Test t = new Test();
        t.Name = "My Test";
        // Note: parameterless lambda expression
        PrintPropValue(() => t.Name);

        // Demonstration that the reference to t has been captured,
        // not just the name:

        Func<string> lambda = () => t.Name;
        PrintPropValue(lambda);
        t.Name = "Changed";
        PrintPropValue(lambda);
    }

    private static void PrintPropValue(Func<string> func)
    {
        Console.WriteLine(func.Invoke());
    }
}

答案 1 :(得分:2)

class Program
{
    static void Main(string[] args)
    {
        Test t = new Test();
        t.Name = "My Test";

        //Use a lambda with a free variable
        Func<Test, string> lambda = x => x.Name;
        PrintPropValue(t, lambda);

        //Close the lambda over its free variable.
        //It will refer to the t 
        //captured from the current scope from now on
        //Note: 'lambda' is unchanged, it still can be used 
        //with any 'Test' instance. We just create a (new) 
        //closure using the 'lambda'.
        Func<string> closure = () => lambda(t);
        PrintPropValue(closure);

        //This will still print 'My Test',
        //despite the fact that t in that scope 
        //refers to another variable.
        AnotherT(closure);

        t.Name = "All your " + t.Name + " captured and are belong to us.";
        //This will now print 'All your My Test captured and are belong to us.'
        AnotherT(closure);

    }

    private static void AnotherT(Func<string> closure)
    {
        Test t = new Test();
        t.Name = "My Another Test";

        PrintPropValue(closure);

    }

    private static void PrintPropValue<T>(T instance, Func<T, string> func)
    {
        Console.WriteLine(func(instance));
    }

    private static void PrintPropValue(Func<string> func)
    {
        Console.WriteLine(func());
    }

}