为什么添加到委托的函数需要是静态的?

时间:2012-03-21 12:58:18

标签: c# methods delegates

我宣布代表:

public delegate void Del(string message);

然后我创建了一个我想要添加到委托中的函数:

public static void DelegateMethod(string message)
{
    System.Console.WriteLine(message);
}

现在我将该函数添加到委托并调用它:

Del handler = new Del( DelegateMethod);
handler("Hello World");
Console.Read();

为什么当我从DelegateMethod中删除static时出现错误?

为什么我委托的功能必须是静态的?

5 个答案:

答案 0 :(得分:3)

  

为什么当我从DelegateMethod中删除“静态”时出现错误?

因为您在静态方法中编写此代码。鉴于您使用的是Console.Read,我认为您已将此代码放在控制台应用程序的static void Main方法中。如果您想从方法中删除 static关键字,则需要包含此方法的类的实例。像这样:

class Program
{
    public delegate void Del(string message);

    public void DelegateMethod(string message)
    {
        System.Console.WriteLine(message);
    }

    static void Main()
    {
        Del handler = new Del(new Program().DelegateMethod);
        handler("Hello World");
        Console.Read();
    }
}

答案 1 :(得分:1)

你错误的是需要使用静态方法的代表。

方法签名(返回类型和参数 - 类型,数量和顺序)需要与委托匹配才能与其兼容。

来自MSDN - Delegates (C# Programming Guide)

  

可以将任何与委托签名匹配的可访问类或结构中的任何方法(包括返回类型和参数)分配给委托。 该方法可以是静态方法,也可以是实例方法

(强调我的)


使用实例方法作为委托目标时,必须引用实际实例:

public class MyClass
{
    public static void DelegateMethod(string message)
    {
        System.Console.WriteLine(message);
    }
}

var myClass = new MyClass();
Del handler = new Del(myClass.DelegateMethod);

答案 2 :(得分:1)

它不需要是静态的,但非静态方法需要一个实例。这是非静态(实例)方法的定义。您可以将实例方法(和实例)传递给委托,如下所示:

Del handler = new Del(instanceVariable.DelegateMethod);

您可以在同一个类的其他实例方法中向委托添加实例方法。假设实例是这样的。

请记住,只要委托实例存在,实例就不符合GC的条件。这有时是对象泄漏的原因(有些人称它们为内存泄漏,尽管泄漏处于更高级别且与C风格内存泄漏不同)

答案 3 :(得分:1)

  

为什么当我从DelegateMethod中删除“静态”时出现错误?

您没有确切地指出您感到困惑的错误。我怀疑您感到困惑的错误是,如果DelegateMethod不是static并且您在static方法中编写代码行,则此行将无法编译类:

Del handler = new Del( DelegateMethod); 

原因是因为如果你没有将DelegateMethod声明为static,那么你需要一个实例来引用该方法。鉴于您的代码可能是用包含类的static方法编写的,因此没有隐式this,因此您需要一个显式实例。假设您的包含类名为Foo

Foo foo = new Foo();
Del handler = ne Del(foo.DelegateMethod);

请参阅?

答案 4 :(得分:0)

这里只是一个猜测。是包含此代码的方法:

Del handler = new Del( DelegateMethod);
handler("Hello World");
Console.Read();

还静止吗?在这种情况下,DelegateMethod也必须是静态的,因为你不能从静态方法中引用非静态方法。