下面的代码创建了一个带有Action
s的字典。
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;
}
}
我知道这里有很多变通方法,你的变通方法可能比这更简单,但这只是另一种方法。但我认为仅仅获得一个更简单的语法是不值得的。