非静态类方法可以添加到Dictionary,但不能使用集合初始值设定项



下面的代码创建了一个带有Actions的字典。

class Test
{
private Dictionary<string, Action> ActionLookup = new();
public Test()
{
ActionLookup.Add("key", SampleAction);
}
protected virtual void SampleAction()
{
// Do something useful here...
}
}

该代码有效。但是,下面的版本给了我一个编译错误。

class Test
{
private Dictionary<string, Action> ActionLookup = new()
{
["key"] = SampleAction  // ERROR CS0236
};
protected virtual void SampleAction()
{
// Do something useful here...
}
}

错误CS0236字段初始值设定项无法引用非静态字段、方法或属性

当手动添加SampleAction完全有效时,为什么不能使用集合初始值设定项将其添加到字典中?

我知道我可以使用以下方法来解决问题,但为什么这是必要的?

class Test
{
private Dictionary<string, Action<MyClass>> ActionLookup = new()
{
["key"] = o => o.SampleAction()
};
protected virtual void SampleAction()
{
// Do something useful here...
}
}

注意:不能将SampleAction设为静态,因为我需要它为virtual

发生这种情况是因为您访问SampleAction的上下文发生了更改。在第一个代码中,它是一个实例方法,在第二个代码中它是字段初始化器。

有一个简单的解决方法,通过使用表达式体将ActionLookup转换为属性(注意=>而不是=(:

private Dictionary<string, Action> ActionLookup => new()
{
["key"] = SampleAction  // ERROR CS0236
};

但是,每次访问该属性时,都会创建字典。

你可以通过使用一个支持字段来修复它:

private Dictionary<string, Action> _actionLookup;
private Dictionary<string, Action> ActionLookup
{
get
{
if (_actionLookup != null)
{
_actionLookup = new Dictionary<string, Action>() { ["key"] = SampleAction };
}
return _actionLookup;
}
}

我知道这里有很多变通方法,你的变通方法可能比这更简单,但这只是另一种方法。但我认为仅仅获得一个更简单的语法是不值得的。

相关内容

最新更新