为什么 .NET 委托不能声明为静态?
当我尝试编译以下内容时:
public static delegate void MoveDelegate (Actor sender, MoveDirection args);
我收到错误:“修饰符‘静态’对于此项无效。”
我在一个单例中实现这个,有一个单独的类调用委托。问题是,当我在另一个类中使用单例实例来调用委托(从标识符,而不是类型)时,无论出于何种原因,我都无法这样做,即使我将委托声明为非静态的也是如此。显然,当且仅当委托是静态的时,我才能直接通过类型引用它。
这背后的原因是什么?我正在使用 MonoDevelop 2.4.2。
更新
使用以下代码尝试其中一项建议后:
public void Move(MoveDirection moveDir)
{
ProcessMove(moveDir);
}
public void ProcessMove(MoveDirection moveDir)
{
Teleporter.MoveMethod mm = new Teleporter.MoveMethod(Move);
moveDelegate(this, moveDir);
}
我收到一个处理错误,该错误指出 MoveMethod 必须是类型,而不是标识符。
When I try to compile the following:
public static delegate void MoveDelegate (Actor sender, MoveDirection args);
I receive, as an error: "The modifer 'static' is not valid for the this item."
I'm implementing this within a singleton, with a separate class which calls the delegate. The problem is that when I use the singleton instance within the other class to call the delegate (from the identifier, not the type), I can't do that for whatever reason, even when I declare the delegate non-static. Obviously, I can only refer to it via the type directly if and only if the delegate is static.
What is the reasoning behind this? I am using MonoDevelop 2.4.2.
update
After trying one of the suggestions with the following code:
public void Move(MoveDirection moveDir)
{
ProcessMove(moveDir);
}
public void ProcessMove(MoveDirection moveDir)
{
Teleporter.MoveMethod mm = new Teleporter.MoveMethod(Move);
moveDelegate(this, moveDir);
}
I've received a processing error, which states that the MoveMethod must be a type, and not an identifier.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
试试这个:
所以方法变量可以定义为静态的。关键字
static
对于delegate
定义没有任何意义,就像enum
或const
定义一样。如何分配静态方法字段的示例:
Try this:
So the method-variable can be defined static. The keyword
static
has no meaning for thedelegate
definition, just likeenum
orconst
definitions.An example of how to assign the static method-field:
您正在声明一个
delegate
类型。将其声明为静态没有任何意义。不过,您可以将delegate
类型的实例声明为static
。You are declaring a
delegate
type. It doesn't make any sense to declare it asstatic
. You could declare an instance of yourdelegate
type asstatic
, though.委托声明基本上声明了一个方法签名,其中仅包含有关其参数和返回类型的信息。由于同一个委托可以指向静态方法和实例方法,因此将方法签名本身设置为静态或实例是没有意义的。
一旦您将委托声明为:
这意味着该类型的任何委托都必须指向一个接受一个
Actor
参数、一个MoveDirection
参数并返回的方法void
,无论该方法是静态方法还是实例方法。您可以在命名空间范围内或在类内部声明委托(就像声明嵌套类一样)。因此,在某处声明
MoveDelegate
后,您可以创建该类型的字段和变量:并记住该方法应该具有匹配签名:
然后您可以将此方法分配给其他地方的委托:
了解 .NET(从版本 v3.5 开始)提供了一些预定义的通用委托(
Action
和Func< /code>) 可以使用而不是声明您自己的委托:恕
我直言,使用这些委托更具可读性,因为您可以通过查看委托本身立即识别参数的签名(而在您的情况下,需要查找声明)。
A delegate declaration basically declares a method signature, which only includes information about its parameters and return type. And since the same delegate can point to both static and instance methods, it doesn't make sense to make the method signature itself static or instance.
Once you have declared your delegate as:
it means that any delegate of this type must point to a method which accepts one
Actor
parameter, oneMoveDirection
parameter, and returnsvoid
, regardless of whether the method is static or instance. You can declare the delegate at namespace scope, or inside a class (just like you would declare a nested class).So after declaring the
MoveDelegate
somewhere, you can the create fields and variables of that type:and remember that the method should have a matching signature:
then you can assign this method to a delegate at some other place:
It is useful to know that .NET (starting from version v3.5) provides some predefined generic delegates (
Action
andFunc
) which can be used instead of declaring your own delegates:Using those delegates is IMHO more readable, since you can immediately identify parameters' signature from looking at the delegate itself (while in your case one needs to look for the declaration).
定义您的委托,在静态类中为其声明一个实例变量。
define your delegate, in your static class declare an instance variable for it.
委托声明实际上是一种类型声明。它不能是静态的,就像不能定义静态枚举或结构一样。
但是,我宁愿使用接口而不是原始委托。
考虑一下:
在您的调用代码中:
这在精神上与 策略设计模式 类似,并且允许您将
Actor
移动与实际实施策略(控制台、图形等)分离。稍后可能需要其他策略方法,这使其成为比委托更好的选择。最后,您可以使用控制反转框架在您的 Actor 类中自动注入正确的策略实例,因此无需手动初始化。
Delegate declaration is actually a type declaration. It cannot be static, just like you cannot define a static enum or structure.
However, I would rather use an interface instead of raw delegate.
Consider this:
In your calling code:
This similar in spirit to Strategy design pattern and allows you to decouple
Actor
movement from the actual implementation strategy (console, graphic, whatever). Other strategy methods may later be required which makes it a better choice than a delegate.Finally, you can use an Inversion of Control framework to automatically inject correct strategy instance in your
Actor
classes so there is no need for manual initialization.让我告诉您声明委托时发生了什么。
编译器创建一个类,在本例中名为
MoveDelegate
,并使用System.MulticastDelegate
扩展它。因为您不能通过静态类型扩展任何非静态类型。
所以这就是编译器不允许静态委托声明的原因。
但您仍然可以拥有静态委托引用。
Let me tell you what happened when you declared a delegate
The compiler creates a class, in this case named
MoveDelegate
, and extends it withSystem.MulticastDelegate
.Since you can not extend any non static type by static type.
So this is the reason why the compiler does not allow static delegate declaration.
But still you can have static delegate reference.