你能在静态上下文中引用非静态方法吗?

时间:2011-10-02 09:03:14

标签: c# .net

委托的使用遵循与调用方法相同的规则 - 如果允许显式调用该方法,则只能通过委托引用方法,这意味着您无法从静态方法引用非静态方法,甚至如果你实际上没有打电话给它。有办法吗?

以下是执行Bowling Kata时使用的一些代码,其中我的理想代码行显示在注释中。我被迫通过静态调用(和匿名静态方法声明)来使框架类代码声明为我喜欢:

    public int FrameScore()
    {
        return scorer[FrameType()](this);
        // I would like it to be
        // return this.scorer[FrameType()]();
    }

    static Dictionary<LinkedFrame.FrameTypeEnum, Func<LinkedFrame, int>> scorer =
        new Dictionary<LinkedFrame.FrameTypeEnum, Func<LinkedFrame, int>>()
        {
            {LinkedFrame.FrameTypeEnum.Strike, frame => frame.StrikeScore()},
            {LinkedFrame.FrameTypeEnum.Spare, frame => frame.SpareScore()},
            {LinkedFrame.FrameTypeEnum.Regular, frame => frame.RegularScore()}
            // I would like an element to be
            // {LinkedFrame.FrameTypeEnum.Strike, StrikeScore}
        };

    private int RegularScore()
    {
        return this.Sum;
    }

    private int SpareScore()
    {
        ...
    }

    private int StrikeScore()
    {
        ...
    }

因此,在某些情况下,在静态上下文中推理非静态方法是有意义的。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:4)

也许开放的实例代表会有所帮助?

根据MSDN: Delegate Class

  

当委托表示在其第一个参数(最常见的情况)上关闭的实例方法时,委托存储对方法的入口点的引用以及对称为目标的对象的引用,该对象具有可分配给的类型。定义方法的类型。当委托表示开放实例方法时,它存储对方法入口点的引用。委托签名必须在其形式参数列表中包含隐藏的this参数;在这种情况下,委托没有对目标对象的引用,并且在调用委托时必须提供目标对象。

归结为,您可以偷偷地将实例方法转换为具有显式this参数的静态方法。你可以在这里看到它是如何完成的:Simon Cooper: Introduction to open instance delegates

答案 1 :(得分:3)

实例方法总是需要使用。

调用实例

如果要通过委托调用实例方法,则有两个选项:

  1. 委托以某种方式捕获实例。
  2. 您需要将实例传递给代理。
  3. 您似乎希望拥有一个不捕获实例且不需要传递实例的委托。这在C#中是不可能的。