首页 > 解决方案 > [C#][事件] 这是正确的吗?c#新手

问题描述

一直在尝试学习 c# 并尝试事件。已经尝试过了,并得到了一些功能。查看我的代码时,它看起来很奇怪,因为我必须为每个订阅者创建新对象,然后订阅发布者。我是否需要创建新对象,然后使用该对象订阅发布者?

程序.cs

namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            ExternalClass potato = new ExternalClass();
            potato.Start();
            
        }
    }
}

外部类.cs

using System;

namespace ConsoleApp1
{
    class ExternalClass
    {
    
        //This is the event, which is the actual event you call to trigger all of the other method/function calls.
    
        public void Start()
        {
            string SubscribeMessage = "Subscribing...";
            string UnsubscribeMessage = "Unsubscribing";
            Apple potato = new Apple();
            Orange beet = new Orange();
            //adding a function to an event
            Console.WriteLine(SubscribeMessage);
            potato.MyEvent += potato.helloWorld;
            potato.MyEvent += beet.DisplayOrange;
            potato.OnEventSuccess();
            //unsubscribing from an event
            Console.WriteLine(UnsubscribeMessage);
            potato.MyEvent -= beet.DisplayOrange;
            potato.MyEvent -= potato.helloWorld;
            potato.OnEventSuccess();
        
        }
    }
}

苹果.cs

using System;

namespace ConsoleApp1
{
    class Apple
    {
        public event Action MyEvent;
    
        //This is the function that you wish to call when you call the event. All other function/method calls must have the same shape as the delegate
        public void helloWorld()
        {
            Console.WriteLine("Hello world!");
        }

        public void OnEventSuccess()
        {
            //myEvent?.Invoke();
            if (MyEvent != null)
            {
                MyEvent?.Invoke();
            }
            else
            {
                Console.WriteLine("Event is empty!");
            }
        }
    }
}

橙色.cs

using System;

namespace ConsoleApp1
{
    public class Orange
    {
        public void DisplayOrange()
        {
            Console.WriteLine("Orange is functioning");
        }
    }
}

样本输出:

Subscribing...
Hello world!
Orange is functioning
Unsubscribing
Event is empty!

标签: c#events

解决方案


到目前为止,您的代码还可以。

对于您的问题:

看起来您觉得创建新订阅者不好。我会说目前还可以,除非您提供有关代码的更多上下文。

事件是一种让两个对象在解耦的同时进行通信的方式,因此订阅者或发布者的生命周期无关紧要。只需确保它们在触发事件时同时存在,并在未使用时取消订阅它们。

但是,您的代码“可能”有潜在的内存泄漏。假设这potato是一个成员变量,它的寿命比beet.

一旦退订前发生任何异常,它永远不会退订,并且beet将与potato.

    Apple potato = new Apple();
    public void Start()
    {
        string SubscribeMessage = "Subscribing...";
        string UnsubscribeMessage = "Unsubscribing";
        Orange beet = new Orange();
        //adding a function to an event
        Console.WriteLine(SubscribeMessage);
        potato.MyEvent += potato.helloWorld;
        potato.MyEvent += beet.DisplayOrange;
        potato.OnEventSuccess();

        // .... another operation
        // Something bad happened on the operation.
        // An exception is thrown then it never goes to Unsubscribe part.
        //unsubscribing from an event
        Console.WriteLine(UnsubscribeMessage);
        potato.MyEvent -= beet.DisplayOrange;
        potato.MyEvent -= potato.helloWorld;
        potato.OnEventSuccess();
    
    }

参考:如何避免事件处理程序内存泄漏


推荐阅读