C# 我们能否创建一个非';你喜欢什么?

C# 我们能否创建一个非';你喜欢什么?,c#,events,C#,Events,在《深度》一书中,Jon Skeet说: 开发人员经常混淆事件和委托实例,或者用委托类型声明的事件和字段 在阅读了他的解释之后,我明白了很多,尽管我仍然对事件到底是什么感到困惑。从下面的代码来看,事件所做的一切似乎都是约束一个类对另一个类中的委托字段的访问 。。。您通常不希望类外的代码能够任意更改(或调用)事件的处理程序。。。[因此]编译器将声明转换为具有默认添加/删除实现的事件和相同类型的私有字段 换句话说,由于访问控制,事件与委托不同。或者这仅仅是为了Jon所说的“现场事件” 类字段事件与

在《深度》一书中,Jon Skeet说:

开发人员经常混淆事件和委托实例,或者用委托类型声明的事件和字段

在阅读了他的解释之后,我明白了很多,尽管我仍然对事件到底是什么感到困惑。从下面的代码来看,事件所做的一切似乎都是约束一个类对另一个类中的委托字段的访问

。。。您通常不希望类外的代码能够任意更改(或调用)事件的处理程序。。。[因此]编译器将声明转换为具有默认添加/删除实现的事件和相同类型的私有字段

换句话说,由于访问控制,事件与委托不同。或者这仅仅是为了Jon所说的“现场事件”

  • 类字段事件与事件不同吗
  • C#中的事件总是类似于字段,还是我们也可以创建不类似于字段的事件
  • 事件和类字段事件之间有什么区别(如果有)
换句话说,C#是否同时支持事件和类场事件,或者这两种说法是一样的

这里的代码示例


类似字段的事件是自动属性的事件等价物,即编译器生成的事件
add
/
remove
访问器

类字段事件

在包含事件声明的类或结构的程序文本中,某些事件可以像字段一样使用。要以这种方式使用,事件不能是抽象的或外部的,也不能显式地包含事件访问器声明。此类事件可以在允许字段的任何上下文中使用。该字段包含一个委托(§15),该委托引用已添加到事件的事件处理程序列表。如果未添加任何事件处理程序,则该字段包含null

(C#5.0规范)


您可以使用C#中的自定义访问器(
add
remove
)实现事件


请参阅。

您可以使用自定义访问器实现事件(添加/删除):您所说的“类字段”到底是什么意思?@LasseV.Karlsen我想知道同样的事情。@LasseV.Karlsen类字段事件是自动属性的事件等价物,即编译器生成的
添加
/
删除
访问器的事件。如果是“类字段事件”是一个后台字段由编译器自动生成的字段,那么是的,您可以声明没有后台字段的事件,自己指定
add/remove
访问器。请参阅@CodesInChaos发布的链接。
using System;
using System.Reflection;

public delegate void TheDelegate(string message);
public static class Program
{
    public static event TheDelegate TheEvent;
    public static TheDelegate DelInstance;
    public static void Main()
    {
        DelInstance = new TheDelegate(TheMethod);
        DelInstance += TheMethod;
        DelInstance.Invoke("Invoke the delegate.");
        PrintMemberInfo(DelInstance.GetType());

        TheEvent += TheMethod;
        TheEvent += TheMethod;
        TheEvent.Invoke("Invoke the event.");
        PrintMemberInfo(TheEvent.GetType());        

        new AnotherClass();
    }

    // Create a method for a delegate. 
    public static void TheMethod(string message)
    {
        Console.WriteLine(message);
    }

    public static void PrintMemberInfo(System.Type t)
    {
        foreach (MemberInfo m in t.GetMembers())
        {
            Console.Write(m.Name + ", ");
        }
        Console.WriteLine("\n");
    }
}

public class AnotherClass
{
    public AnotherClass()
    {
        Program.DelInstance += new TheDelegate(AnotherMethod);
        Program.DelInstance.Invoke("Another class");

        // Error... we can only call += or -+
        // Program.TheEvent.Invoke();
    }

    public void AnotherMethod(string message)
    {
        Console.WriteLine(message);
    }
}
event EventHandler IDrawingObject.OnDraw
{
    add
    {
        ...
    }
    remove
    {
        ...
    }
}