zeb*_*und 23 c# delegates compiler-errors
当我尝试编译以下内容时:
public static delegate void MoveDelegate (Actor sender, MoveDirection args);
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:"modifer'static'对此项无效."
我在一个单例中实现它,有一个单独的类调用委托.问题是,当我在另一个类中使用单例实例来调用委托时(来自标识符,而不是类型),我无论出于何种原因都不能这样做,即使我声明委托是非静态的.显然,当且仅当委托是静态的时候,我才能直接通过类型引用它.
这背后的原因是什么?我使用的是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);
}
Run Code Online (Sandbox Code Playgroud)
我收到了一个处理错误,指出MoveMethod必须是一个类型,而不是标识符.
Cha*_*erg 34
试试这个:
public delegate void MoveDelegate(object o);
public static MoveDelegate MoveMethod;
Run Code Online (Sandbox Code Playgroud)
所以方法变量可以定义为static.关键字static先后为没有意义delegate的定义,就像enum或const定义.
如何分配静态方法字段的示例:
public class A
{
public delegate void MoveDelegate(object o);
public static MoveDelegate MoveMethod;
}
public class B
{
public static void MoveIt(object o)
{
// Do something
}
}
public class C
{
public void Assign()
{
A.MoveMethod = B.MoveIt;
}
public void DoSomething()
{
if (A.MoveMethod!=null)
A.MoveMethod(new object());
}
}
Run Code Online (Sandbox Code Playgroud)
你是在声明一种delegate类型.声明它是没有任何意义的static.但是,您可以将delegate类型的实例声明为static.
public delegate void BoringDelegate();
internal class Bar {
public static BoringDelegate NoOp;
static Bar() {
NoOp = () => { };
}
}
Run Code Online (Sandbox Code Playgroud)
委托声明基本上声明了一个方法签名,它只包含有关其参数和返回类型的信息.由于同一个委托可以指向静态方法和实例方法,因此将方法签名本身设置为静态或实例是没有意义的.
一旦您将您的代表声明为:
public delegate void MoveDelegate (Actor sender, MoveDirection args);
Run Code Online (Sandbox Code Playgroud)
这意味着此类型的任何委托都必须指向一个接受一个Actor参数,一个MoveDirection参数并返回void的方法,无论该方法是静态还是实例.您可以在命名空间作用域或类内声明委托(就像您声明嵌套类一样).
因此,在声明了MoveDelegate某个地方之后,您可以创建该类型的字段和变量:
private MoveDelegate _myMoveDelegate;
Run Code Online (Sandbox Code Playgroud)
并记住该方法应具有匹配的签名:
// parameters and return type must match!
public void Move(Actor actor, MoveDirection moveDir)
{
ProcessMove (moveDir);
}
public static void MoveStatic(Actor actor, MoveDirection moveDir)
{
ProcessMove (moveDir);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以将此方法分配给其他地方的委托:
private void SomeOtherMethod()
{
// get a reference to the Move method
_myMoveDelegate = Move;
// or, alternatively the longer version:
// _myMoveDelegate = new MoveDelegate(Move);
// works for static methods too
_myMoveDelegate = MoveStatic;
// and then simply call the Move method indirectly
_myMoveDelegate(someActor, someDirection);
}
Run Code Online (Sandbox Code Playgroud)
知道.NET(从版本v3.5开始)提供了一些预定义的通用委托(Action和Func),而不是声明自己的委托,这很有用:
// you can simply use the Action delegate to declare the
// method which accepts these same parameters
private Action<Actor, MoveDirection> _myMoveDelegate;
Run Code Online (Sandbox Code Playgroud)
使用这些代表是恕我直言更具可读性,因为您可以通过查看代表本身立即识别参数的签名(在您的情况下,需要查找声明).