由于我正在编写一个通用概念,以便执行某些操作,因此需要在Action委托中调用一些非静态方法。 此外,我的代码中没有任何静态方法。 但是,我仍然无法在Action定义内部调用非静态方法。以下是我的代码-
private Dictionary<string, Action<object>> m_dicUndoRedoAction = new Dictionary<string, Action<object>>();
m_dicUndoRedoAction.Add("DeleteClass", DeleteClassFromeNode );
这里是DeleteClass的定义
private Action<object> DeleteClassFromeNode =
data =>
{
Tuple<itemType1, itemType2> items = data as Tuple<itemType1, itemType2>;
if (items != null && items.Item2 != null)
{
DeleteClass(items.Item2); // This is my non static method in the same class.
}
};
这是我调用委托的方式
private void Undo_Executed(object sender, ExecutedRoutedEventArgs e)
{
object temp;
if (UndoRedoAction.DoUndo(out temp))
{
m_dicUndoRedoAction["DeleteClass"].Invoke(temp);
}
}
编译器报错
字段初始化程序不能引用非静态字段、方法或属性 'DeleteClassFromeNode'
我还查阅了 Action 的 MSDN 参考文献,但是微软没有提到 Action 是否隐式地是静态的,或者我是否走错了路? 我也查阅了一些从静态方法中调用非静态方法的内容,但没有一个令人满意地解释。 如果有人能提供更低级别的解释,我将不胜感激。
响应 Peter 的解释
尽管初始化程序在构造函数完成之前运行,但这并不会触发构造函数执行期间的委托。即使您在 ILDASM 中查看其程序集代码,它显示实际的 Action Field 是非静态的,但缓存的匿名委托对象是静态的。为什么编译器会有这种不同的行为?
private Action<object> DeleteClassFromeNode = ...
看起来有些奇怪。为什么不能像private void DeleteClassFromeNode(object data) { ... }
一样将其作为一个方法呢?如果你担心的是编译问题,那么m_dicUndoRedoAction.Add("DeleteClass", DeleteClassFromeNode );
仍然可以编译通过。 - user743382=>
仍将被编译器转换为方法。在您的情况下,最好使用名称DeleteClassFromeNode
来命名该方法。当然,命名方法(非静态)的主体可以引用此实例的其他实例成员。正如hvd所说,“方法组”DeleteClassFromeNode
隐式转换为类型Action<object>
。也许方法参数data
的类型应该是一些Tuple<,>
而不仅仅是object
?请注意,Action<in T>
在T
中是逆变的。 - Jeppe Stig Nielsen