【问题标题】:Why can't a delegate refer to a non-static method when used in a static method?为什么委托在静态方法中使用时不能引用非静态方法?
【发布时间】:2010-02-19 19:26:36
【问题描述】:

为什么在 C# 中使用委托时需要将函数设为 STATIC?

class Program
{
    delegate int Fun (int a, int b);
    static void Main(string[] args)
    {
        Fun F1 = new Fun(Add);
        int Res= F1(2,3);
        Console.WriteLine(Res);
    }

   **static public int Add(int a, int b)** 
    {
        int result;
        result = a + b;
        return result;
    }
}

【问题讨论】:

  • 因为您试图在 Main 的静态上下文中引用它?
  • 我否认这个问题的前提; 不需要使方法静态。需要向委托提供足够的信息才能成功调用方法;对于非静态方法,包括提供接收非静态方法调用的实例。

标签: c# .net visual-studio-2005 function delegates


【解决方案1】:

这不是“必要的”。但是你的Main方法是static,所以它不能调用非static的方法。尝试这样的事情(这不是一个真正的好方法——你确实应该创建一个新类,但它不会对你的示例有太大的改变):

class Program 
{ 
    delegate int Fun (int a, int b); 
    void Execute()
    {
       Fun F1 = new Fun(Add); 
       int Res= F1(2,3); 
       Console.WriteLine(Res); 
    }

    static void Main(string[] args) 
    { 
        var program = new Program();
        program.Execute();
    } 

    int Add(int a, int b)
    { 
        int result; 
        result = a + b; 
        return result; 
    } 
}

【讨论】:

  • 用代码反驳你自己的主张做得很好。显然 Main (一个静态方法)通过调用它来引用 Execute (一个实例方法)。正确的说法是“对于另一个类的静态方法或方法来引用实例方法,它必须在这样做时提供实例”。同一类中的实例方法在引用实例方法时也必须提供实例(检查 IL 以查看 this),但 C# 编译器默认为“this”,即您不指定。
【解决方案2】:

您的函数必须是静态的,因为您是从静态方法 Main 调用的。您可以使方法非静态:

class Program
{
    delegate int Fun (int a, int b);
    static void Main(string[] args)
    {
        Program p = new Program();       // create instance of Program
        Fun F1 = new Fun(p.Add);         // now your non-static method can be referenced
        int Res= F1(2,3);
        Console.WriteLine(Res);
    }

    public int Add(int a, int b)
    {
        int result;
        result = a + b;
        return result;
    }
}

【讨论】:

    【解决方案3】:

    在这种情况下,因为您没有创建任何类的实例,所以唯一的选择是静态函数。如果您要实例化一个 Program 类型的对象,那么您可以使用实例方法。

    【讨论】:

      【解决方案4】:

      委托基本上遵循与方法相同的规则。在提供的示例中,您的委托必须是静态的,因为您是从静态方法调用它。同样,这也行不通:

      static void Main(string[] args)
      {
          int Res = Add(3, 4);
          Console.WriteLine(Res);
      }
      
      public int Add(int a, int b)
      {
          int result;
          result = a + b;
          return result;
      }
      

      但是,如果您像这样将事物移动到非静态上下文中:

      class MyClass
      {
          public MyClass()
          {
              Fun F1 = new Fun(Add);
              int Res = F1(2, 3);
              Console.WriteLine(Res);
          }
      
          public int Add(int a, int b)
          {
              int result;
              result = a + b;
              return result;
          }
      }
      

      你可以有一个非静态方法的委托。

      【讨论】:

      • 这不是真的,您可以从静态上下文委托给非静态方法。例如。 MyDelegate del = foo.Bar;即使 Bar 不是静态的并且分配在静态上下文中也是有效的。
      【解决方案5】:

      无需创建静态方法来传递委托。

      但是非静态方法应该在不同的类中声明,并且必须使用该类的实例来访问。

      DelegateName DN = new DelegateName(类的实例。方法名称)

      【讨论】:

        猜你喜欢
        • 2011-03-02
        • 2012-07-02
        • 1970-01-01
        • 2018-10-27
        • 1970-01-01
        • 2011-09-10
        • 2011-12-11
        • 2010-09-29
        • 1970-01-01
        相关资源
        最近更新 更多