C# 应用程序中的事件语法与委托语法

Event syntax vs delegate syntax in c# application

我搜索了 the use of event syntax and its importance in c# code。所以我发现了这些优点:

  1. 无法直接分配事件(我们不存在有人删除所有先前订阅的风险,就像委托语法一样
  2. 没有外部用户可以提出该事件

我写这个片段是为了更好地理解上面的这些要点:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace certiflibrary
{
    public class Class1
    {
        public static void Main()
        {
            Pub p = new Pub();
            p.OnChange += () => Console.WriteLine("First");
            p.OnChange += () => Console.WriteLine("Second");
            p.OnChange = () => Console.WriteLine("Third");
            p.Raise();
            Console.ReadKey();
            Console.WriteLine(p.OnChange.GetInvocationList().Length);
            Console.ReadKey();

            PubEvent pubevent = new PubEvent();
            pubevent.OnchangeEvent += (sender, e) => Console.WriteLine("Event Raised: {0}",e.Name);
            pubevent.Raise();
            Console.ReadKey();
        }
    }

    public class Pub
    {
        public Action OnChange { get; set; }

        public void Raise()
        {
         if(OnChange != null)
         {
             OnChange();
         }
        }
    }

    public class PubEvent
    {

        public event EventHandler<SpecialArgs> OnchangeEvent = delegate { };

        public void Raise()
        {
            OnchangeEvent(this, new SpecialArgs("hello"));
        }
    }

    public class SpecialArgs:EventArgs
    {
        public SpecialArgs(string _name)
        {
         Name= _name;
        }

        public string Name { get; set; }
    }
}

第一点很明确:我不能直接分配一个事件。但是我不明白第二个,即使在我的代码中我也可以从 class 外部访问事件并引发它。

那么,事件语法如何防止不需要的用户引发事件?

您在 class 中定义了引发事件的方法。

如果此方法是 public 任何人都可以调用该方法。

事件系统会阻止 pubevent.OnchangeEvent(...)

之类的事情

even in my code I can access to the event from outside the class and raise it

不,你不能。

你可以打电话给

p.OnChange()

因为OnChange是一个简单的属性,但是你不能调用

pubevent.OnchangeEvent()

因为 OnchangeEvent 是一个事件。

编译器会抱怨

The event 'UserQuery.PubEvent.OnchangeEvent' can only appear on the left hand side of += or -= (except when used from within the type 'UserQuery.PubEvent')

因此,您只能从 PubEvent class 内部调用 OnchangeEvent,这正是您在 Raise 方法中所做的。 OnchangeEvent不能从外面养。