为什么声明为实例字段的 lambda 委托只能访问静态成员?

Why a lambda delegate declared as an instance field can only access static members?

我有这个:

public class Demo {

    private IService _service;
    
    Action<Guid> action = v => _service.CallServiceWithParameter(v);

}

我收到错误:

Cannot access non-static field '_service' in static context

嗯?静态上下文在哪里?为什么 lambda 必须是静态的? lambda 本身是 not static...

字段初始值设定项不能引用非静态成员。您需要将 _service 更改为:

private static IService _service;

或者您可以将其移至构造函数。

public class Demo
{
    private IService _service;
    private Action<Guid> action;

    public Demo(IService service)
    {
        _service = service;
        action = v => _service.CallServiceWithParameter(v);
    }
}

字段初始值设定项是静态语句,在执行构造函数之前进行评估,这就是它们只能访问其他静态项的原因。

如果您尝试用方法调用替换初始值设定项,就会看到这一点;只有当你将该方法设为静态时,它才会编译。

这是一个可运行的演示 fiddle:https://dotnetfiddle.net/IVtMHJ

来自 fiddle 的代码:

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Demo is going to be created");
        var d = new Demo();
        Console.WriteLine("Demo has been created");
    }
}

public class Demo
{
    public Demo()
    {
        Console.WriteLine("Running constructor");
    }

    private IService _service;
    
    Action<Guid> action = CreateAction();
    
    public static Action<Guid> CreateAction() // Will get compile error above if we remove "static" here
    {
        Console.WriteLine("Running CreateAction");
        return null;
    }
}

public interface IService { }

输出:

Demo is going to be created
Running CreateAction
Running constructor
Demo has been created

如果将 CreateAction 调用移动到构造函数中,则可以使其成为非静态的:

public Demo()
{
    Console.WriteLine("Running constructor");
    action = CreateAction();
}

private IService _service;

Action<Guid> action;

public Action<Guid> CreateAction() // Now it does not need to be "static"
{
    Console.WriteLine("Running CreateAction");
    return null;
}

输出(来自fiddle):

Demo is going to be created
Running constructor
Running CreateAction
Demo has been created