为什么.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必须是类型,而不是标识符。


尝试这个:

public delegate void MoveDelegate(object o);
public static MoveDelegate MoveMethod;

所以方法变量可以定义为static。 关键字staticdelegate定义没有任何意义,就像enumconst定义一样。

一个如何分配静态方法字段的例子:

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()); 
  }
}

您正在声明delegate类型。 将它声明为static是没有任何意义的。 不过,您可以将您的delegate类型的实例声明为static

public delegate void BoringDelegate();


internal class Bar {
    public static BoringDelegate NoOp;
    static Bar() {
        NoOp = () => { };
    }
}

委托声明基本上声明了一个方法签名 ,它只包含有关其参数和返回类型的信息。 由于同一个委托可以同时指向静态方法和实例方法,因此将方法签名本身设为静态或实例是没有意义的。

一旦你宣布你的委托为:

public delegate void MoveDelegate (Actor sender, MoveDirection args);

这意味着此类型的任何委托都必须指向一个接受一个Actor参数(一个MoveDirection参数)并返回void的方法,无论该方法是静态还是实例。 您可以在命名空间范围或类中声明委托(就像您将声明嵌套类一样)。

因此,在声明MoveDelegate之后,您可以创建该类型的字段和变量:

private MoveDelegate _myMoveDelegate;

并记住该方法应该有一个匹配的签名:

// 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);
}

那么你可以将这个方法分配给其他地方的代理:

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);
}

知道.NET(从版本v3.5开始)提供了一些预定义的通用委托ActionFunc ),可以使用它来代替声明自己的委托

// you can simply use the Action delegate to declare the
// method which accepts these same parameters
private Action<Actor, MoveDirection> _myMoveDelegate;

使用这些代表是更加可读的,因为你可以通过查看委托本身来立即识别参数的签名(而在你的情况下需要查找声明)。

链接地址: http://www.djcxy.com/p/82117.html

上一篇: Why can a .NET delegate not be declared static?

下一篇: Help me pick a Dependency Injection framework for .Net