开发者

Can you reference a non-static method in a static context?

Use of del开发者_如何学Pythonegates follows the same rules as calling methods - you can only refer to a method via a delegate if you are allowed to call that method explicitly, which means you cannot reference a non-static method from a static method, even if you don't actually call it. Is there a way around that?

Here is some code used in performing the Bowling Kata, with my ideal lines of code shown in comments. I was forced to go through a static call (and anonymous static method declarations) to make the Frame Class code declarative to my liking:

    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()
    {
        ...
    }

So in some contexts it would make sense to reason about non-static methods in a static context. Is there a way to do this?


Maybe open instance delegates will help?

According to MSDN: Delegate Class:

When a delegate represents an instance method closed over its first argument (the most common case), the delegate stores a reference to the method's entry point and a reference to an object, called the target, which is of a type assignable to the type that defined the method. When a delegate represents an open instance method, it stores a reference to the method's entry point. The delegate signature must include the hidden this parameter in its formal parameter list; in this case, the delegate does not have a reference to a target object, and a target object must be supplied when the delegate is invoked.

What it comes down to, is that you can sneakily convert an instance method to a static method with an explicit this parameter. You can see how it's done here: Simon Cooper: Introduction to open instance delegates


An instance method always requires an instance to be invoked with.

If you want to invoke an instance method through a delegate, you have two options:

  1. The delegate captures the instance in some way.
  2. You need to pass the instance to the delegate.

You seem to want to have a delegate that does not capture an instance and does not require an instance to be passed. That's not possible in C#.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜