繁体   English   中英

为什么活动需要代表? 为什么我们甚至需要活动?

[英]Why do Events need Delegates? Why do we even Need Events?

过去几周我一直对事件感到困惑。 我理解委托如何工作,而不是它如何工作,但足以知道delegate datatype是单个演员委托。 delegate void是一个多播委托 - 方法的引用列表。

我知道委托类型编译成一个类,但不幸的是我仍然不确定如何引用该方法。 例如

delegate void TestDelegate();
TestDelegate testDelegate = new TestDelegate(myObject.SomeMethod) ;

问题1:我认为myObject是目标,SomeMethod是引用的方法,但我只传递一个输入。 那么myObject.SomeMethod被编译成一个字符串,是由句点分割的字符串吗? 荒谬我知道。

问题2:添加到多播委托时

multicastdelegate+=newmethodtobereference
multicastdelegate() ;

调用列表中的每个方法都被调用或通知? 如果这是真的,为什么地狱 ,我需要的事件或event的关键字? 是不是简单地告诉开发人员嘿,这是一个事件? 因为我很困惑,我只想继续这个阶段大声笑。 这是我今天编写的用于测试它是否需要事件关键字的示例代码。

using System;
namespace LambdasETs
{
    public delegate void IsEvenNumberEventHandler(int numberThatIsEven);

    public class IsEvenNumberFound
    {
        public  IsEvenNumberEventHandler IsEvenNumberEvent;
        private int number;

        public void InputNumber(int n)
        {
            if(number %2 ==0)
            {
                if (IsEvenNumberEvent != null)
                {
                    IsEvenNumberEvent(n);
                }
            }
        }


        public static void Main()
        {
            IsEvenNumberFound isEvenNumberFound = new IsEvenNumberFound();

            isEvenNumberFound.IsEvenNumberEvent += IsEvenNumberAction;

             isEvenNumberFound.InputNumber(10);

            Console.ReadLine();

        }

        public static void IsEvenNumberAction(int number)
        {
            Console.WriteLine("{0} is an even number!", number);
        }
    }


}

将event关键字添加到字段public IsEvenNumberEventHandler IsEvenNumberEvent; 没有区别。 请一些人解释一下,这样一个菜鸟可以理解谢谢。

事件是委托的访问者,就像属性是字段的访问者一样。 它有着相同的目标,它可以防止其他代码弄乱委托对象。 就像在你不知道的一堆代码已订阅回调时将其设置为null。 事件限制只能使用+ =和 - =运算符添加和删除事件处理程序,外部代码根本无法访问私有委托对象。

并使用添加和删​​除访问者自定义订阅。 您通常不会这样做,因为您通常对编译器生成的默认访问器感到满意。 包括存储委托的隐藏后备字段。 但是,例如在框架代码中并不罕见。 与System.Windows.Forms.Control支持的许多事件的所有事件处理程序一样,它们都存储在单个EventHandlerList中。 或WPF等效,EventHandlersStore。

但足以知道委托数据类型是单个转换委托。 delegate void是一个多播委托 - 方法的引用列表。

不对。 所有“普通”委托都是多播的,即使它们具有非void返回类型。

问题1:我认为myObject是目标,SomeMethod是引用的方法,但我只传递一个输入。 那么myObject.SomeMethod被编译成一个字符串,是由句点分割的字符串吗? 荒谬我知道。

不, myObject.SomeMethod是一个方法组。 这种委托实例创建方式涉及一些编译器魔术。

multicastdelegate + = newmethodtobereference

如果multicastdelegate是普通的委托变量,这相当于multicastdelegate = multicastdelegate + newmethodtobereference即它创建一个调用多个方法的新委托,并将其分配给multicastdelegate


现在回答你的主要问题:事件的目的是什么?

事件有委托类型。 它们的行为与属性相似。 它们的目的是封装,特别是它们只允许消费者订阅( += )和取消订阅( -= )但不读取事件的价值。

属性是两种方法的组合: getset

事件是两个公共方法subscribeunsubscribe的组合,并且在类似字段的事件的情况下也类似于私有的getter。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM