为什么委托必须是静态的?

8
在下面的代码中,我必须声明方法MdrResponseInterpreterstatic,否则会出现编译错误。
class.... {

    private StandardBuilder _mdrResponseBuilder = 
      new StandardBuilder(MdrResponseInterpreter);

    public static bool MdrResponseInterpreter(DNMessageDeliverer builder, 
                                              DNFieldSet message)
    {
        // .... work
    }

为什么?由于_mdrResponseBuilder不是静态的,所以我希望MdrResponseInterpreter能够访问this
4个回答

11
由于字段初始化器无法访问“this”/实例成员,如果您想要访问实例成员,请将初始化移动到构造函数中。规范表示:实例字段的变量初始化程序不能引用正在创建的实例。因此,在变量初始化程序中引用“this”是编译时错误。尽管您的代码没有明确地引用“this”,但如果该方法是实例成员,则方法组转换为委托转换隐式地引用了“this”。

5
要补充CodeInChaos的回答(它是正确的),您只需将赋值移至构造函数中即可:
private StandartBuilder _mdrResponsBuilder;

public Foo() // Whatever your type is called
{
    // Simpler syntax for creating a delegate, too. Just use a
    // method group conversion...
    _mdrResponsBuilder = MdrResponseInterpreter;
}

编辑:上述假设StandartBuilder是委托类型。如果它是一个带有一个接受委托类型的构造函数的类型,那么你需要回到new StandartBuilder(MdrResponseInterpreter),但仍然将其放在构造函数中。


只是想知道,"_mdrResponsBuilder = MdrResponseInterpreter" 这样写是正确的吗?问题中没有表明 StandardBuilder 是一个委托...它可能是一个在构造函数中接受 Func<DNMessageDeliverer, DNFieldSet, bool> 的类?顺便说一下,我没有给它点踩。 - odalet
1
@odalet:是的,这是可能的。我认为更有可能(考虑到问题标题)它是一个委托类型。将进行编辑以澄清。 - Jon Skeet

1

在初始化器中不允许使用实例成员。

将委托视为具有1)对象引用和2)方法引用。由于您无法访问this,因此没有办法设置对象引用,所以将方法声明为static是将其用作委托的唯一方法(因为静态方法的委托对象引用为null)。将初始化移到构造函数中可以帮助您解决这个问题。


1
那个点肯定有一个对象(否则值被分配到哪里了?),但你现在还不能访问this - Jon Skeet
我仍然认为这不太清楚。对象确实存在,完全存在。它可能没有完全初始化,但构造函数体中也是如此。 (可能还有其他派生的构造函数体尚未运行...) - Jon Skeet

1

该方法必须是静态的,因为它在对象初始化时被调用,而在构造函数开始执行之前。如果您想要访问this,请从构造函数内部调用初始化方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接