The following code creates a dictionary with Actions.
class Test
{
private Dictionary<string, Action> ActionLookup = new();
public Test()
{
ActionLookup.Add("key", SampleAction);
}
protected virtual void SampleAction()
{
// Do something useful here...
}
}
That code works. However, the following version gives me a compile error.
class Test
{
private Dictionary<string, Action> ActionLookup = new()
{
["key"] = SampleAction // ERROR CS0236
};
protected virtual void SampleAction()
{
// Do something useful here...
}
}
Error CS0236 A field initializer cannot reference the non-static field, method, or property
Why can’t I add SampleAction to my dictionary using a collection initializer when it’s perfectly valid to add it manually?
I know I can workaround it using something like the following, but why is this necessary?
class Test
{
private Dictionary<string, Action<MyClass>> ActionLookup = new()
{
["key"] = o => o.SampleAction()
};
protected virtual void SampleAction()
{
// Do something useful here...
}
}
Note: It’s not an option to make SampleAction static because I need it to be virtual.
>Solution :
This is happening because the context you are accessing the SampleAction changes. In the first code it is an instance method, in the second code it’s field initializer.
There is one simple workaround which is turning ActionLookup into a property by using expression bodies (notice the => instead of =):
private Dictionary<string, Action> ActionLookup => new()
{
["key"] = SampleAction // ERROR CS0236
};
But, this will create the dictionary every time you access the property.
You can fix it by using a backing field for it:
private Dictionary<string, Action> _actionLookup;
private Dictionary<string, Action> ActionLookup
{
get
{
if (_actionLookup != null)
{
_actionLookup = new Dictionary<string, Action>() { ["key"] = SampleAction };
}
return _actionLookup;
}
}
I know a lot of workarounds going on here and your workaround may be simpler than this, but it’s just another way to make it work. But I don’t think it is worth just to get a simpler syntax.