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:
- The delegate captures the instance in some way.
- 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#.
精彩评论