C# c代表和活动

C# c代表和活动,c#,events,c#-4.0,delegates,C#,Events,C# 4.0,Delegates,我试图学习c语言中的委托和事件,我知道事件是委托的某种包装,委托是函数/方法的指针 下面是我的代码,但当我运行它时,没有显示任何内容。。。有什么问题吗 public class ClassHandler { public delegate void DoProcesses(); public event DoProcesses DoProcessesEvent; } public class Class1 { public void Func1() {

我试图学习c语言中的委托和事件,我知道事件是委托的某种包装,委托是函数/方法的指针

下面是我的代码,但当我运行它时,没有显示任何内容。。。有什么问题吗

public class ClassHandler
{
    public delegate void DoProcesses();
    public event DoProcesses DoProcessesEvent;
}

public class Class1
{
    public void Func1()
    {
        Console.WriteLine("Class 1 doing function 1");
    }
    public void Func2()
    {
        Console.WriteLine("Class 1 doing function 2");
    }

}

public class Class2
{
    public void Func1()
    {
        Console.WriteLine("Class 2 doing function 1");
    }
    public void Func2()
    {
        Console.WriteLine("Class 2 doing function 2");
    }

}


class Program
{
    static void Main(string[] args)
    {
        Class1 cs1 = new Class1();
        Class2 cs2 = new Class2();
        ClassHandler main = new ClassHandler();
        main.DoProcessesEvent += new ClassHandler.DoProcesses(cs1.Func1);
        main.DoProcessesEvent += new ClassHandler.DoProcesses(cs1.Func2);
        main.DoProcessesEvent += new ClassHandler.DoProcesses(cs2.Func1);
        main.DoProcessesEvent += new ClassHandler.DoProcesses(cs2.Func2);
        main.DoProcessesEvent += new ClassHandler.DoProcesses(ff); // this line here is causing an error: An object reference is required for the non-static field, method, or property 'TryDelegatesAndEvents.Program.ff()'    

        Console.Read();
    }
    public void ff()
    {
        Console.WriteLine("gggg");
    }
}
更新:如何引发事件以使其已执行方法?

此行存在问题:main.doProcessEvent+=new ClassHandler.DoProcessesff

这是因为您的方法ff是一个非静态方法,您不能像从静态方法那样直接访问它

使您的方法ff为静态,或者创建包含类的and对象,并为该方法分配一个实例

注释:您没有看到任何内容的原因是您只是将它们绑定到event DopProcesseSEvent,但您没有在任何地方引发事件。您仅定义事件的处理程序

编辑: 将ClassHandler类更改为:

public class ClassHandler
{
    public delegate void DoProcesses();
    public event DoProcesses DoProcessesEvent;

    public void OnDoProcessEvent()
    {
        if (DoProcessesEvent != null)
            DoProcessesEvent();
    }
}
在主控台前的主方法中;类型:

main.OnDoProcessEvent();
这将引发事件,并从应用程序中进行处理,并提供以下输出

Class 1 doing function 1
Class 1 doing function 2
Class 2 doing function 1
Class 2 doing function 2
gggg

更改main.doProcessEvent+=new ClassHandler.DoProcessesff;to main.doProcessEvent+=new ClassHandler.doProcessNew Program.ff;或者使ff静态

好,由于以下行,它无法编译:

main.DoProcessesEvent += new ClassHandler.DoProcesses(ff); 
VS吐出的错误是:

An object reference is required for the non-static field, method, or property 'ConsoleApplication2.Program.ff()'
只需将ff方法更改为静态即可绕过它

例如:


除了前面评论中指出的问题外,您还必须触发事件

在检查事件是否为null并激发它之前,先复制事件。这将消除线程中的一个潜在问题,即事件在检查null和触发事件之间的位置变为null:

// Copy the event delegate before checking/calling

EventHandler copy = DoProcessesEvent ;  
if (copy != null)     
   copy(this, EventArgs.Empty); // Call any handlers on the copied list 

这将确保触发事件并获得结果。

只是为了补充@Habib的答案,订阅实例类方法作为另一个作用域中潜在对象的事件处理程序是相当不寻常的,例如,如果Class1超出作用域,而main仍有订阅,会发生什么?。更常见的情况是在同一范围内订阅和取消订阅处理程序,通常以异步方式,以下事件仍然同步引发

namespace ConsoleApplication1
{
    public delegate void ProcessCompletedEvent(string description);

    public class Class1
    {
        public void Func1()
        {
            // Do Func1 work
            Thread.Sleep(500);
            RaiseEvent("Func1 completed");
        }
        public void Func2()
        {
            // Do Func2 work
            Thread.Sleep(1000);
            RaiseEvent("Func2 completed");
        }
        private void RaiseEvent(string description)
        {
            if (ProcessCompleted != null)
            {
                ProcessCompleted(description);
            }
        }

        public event ProcessCompletedEvent ProcessCompleted;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Class1 cs1 = new Class1();

            // Wire up event handler
            cs1.ProcessCompleted += new ProcessCompletedEvent(MyHandler);

            cs1.Func1();
            cs1.Func2();

            Console.Read();
            // Remove the subscription
            cs1.ProcessCompleted -= MyHandler;
        }

        // *** Is in the same scope as main, which subscribes / desubscribes
        public static void MyHandler(string description)
        {
            Console.WriteLine(description);
        }
    }
}

然而,当删除该行时。。。在运行时,我仍然看不到控制台中的任何内容…您能给出一个如何引发该事件的示例吗?好的,将其设置为静态,没有错误,但在运行时控制台中没有显示任何内容…您已委派任务,但没有告诉何时执行
namespace ConsoleApplication1
{
    public delegate void ProcessCompletedEvent(string description);

    public class Class1
    {
        public void Func1()
        {
            // Do Func1 work
            Thread.Sleep(500);
            RaiseEvent("Func1 completed");
        }
        public void Func2()
        {
            // Do Func2 work
            Thread.Sleep(1000);
            RaiseEvent("Func2 completed");
        }
        private void RaiseEvent(string description)
        {
            if (ProcessCompleted != null)
            {
                ProcessCompleted(description);
            }
        }

        public event ProcessCompletedEvent ProcessCompleted;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Class1 cs1 = new Class1();

            // Wire up event handler
            cs1.ProcessCompleted += new ProcessCompletedEvent(MyHandler);

            cs1.Func1();
            cs1.Func2();

            Console.Read();
            // Remove the subscription
            cs1.ProcessCompleted -= MyHandler;
        }

        // *** Is in the same scope as main, which subscribes / desubscribes
        public static void MyHandler(string description)
        {
            Console.WriteLine(description);
        }
    }
}