为什么在没有实例化课程的情况下使用委托? [英] Why using delegate without instancing the class?

查看:61
本文介绍了为什么在没有实例化课程的情况下使用委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MyDelegate.cs

 使用系统; 
命名空间 EventsGeneralExample
{
public delegate void ChangedEventHandler( object sender,EventArgs e);
}



在另一个班级 ListWithChangedEvent.cs

< pre lang =c#> namespace EventsGeneralExample
{
public class ListWithChangedEvent:ArrayList
{
// 每当
// 列表更改元素时,客户可以使用该事件进行通知。
public event ChangedEventHandler已更改;



// 调用Changed事件;列表更改时调用
protected virtual void OnChanged(EventArgs e)
{
Console.WriteLine( 列表已更改,事件正在触发);
// 确保订阅的内容
if (已更改!= null
已更改( ,e);
}

// 覆盖一些可以更改列表的方法;
// 在每个
public 覆盖 int 添加(对象
{
Console.WriteLine( 添加到列表);
int i = base .Add( value );
OnChanged(EventArgs.Empty);
return i;
}

public 覆盖 void Clear()
{
Console.WriteLine( Clearing清单);
base .Clear();
OnChanged(EventArgs.Empty);
}

public 覆盖 对象 [ int index]
{
set
{
Console.WriteLine( 在列表中设置项目);
base [index] = value ;
OnChanged(EventArgs.Empty);
}
}
}
}





我的问题是为什么我们不'是否需要实例 MyDelegate 类然后声明事件?

让我们说:

 MyDelegate my =  new  MyDelegate(); 
public event my.ChangedEventHandler已更改;

解决方案

在您的类中,您只需声明事件,实际的委托由侦听器提供。它与声明变量相同,只有这个变量具有更多的语义。它与声明变量相同:

  int  i; 



这说:你可以在这里输入一个int值。你的课基本上是这样说的:当一些重要的事情发生时,我正在解雇这个事件,如果你想得到通知,请提供代表,我会在时机成熟时给它打电话。想要收到通知的人附上一名代表:

 instanceOfListWithChangedEvent.Changed + = myDelegate; 



有查看OnChnaged()方法:

  if (已更改!=  null 
已更改(,e);



这是必要的,因为可能发生没人在听,委托的值为空。



BTW不要命名你的类ListWithChangedEvent,它显然是一个List!


事实上,你的两个类定义共享相同的NameSpace ,允许第二个类在第一个类中使用委托定义:事实上两个类定义在两个不同的.cs文件中......无关紧要。



请注意您使用的是'ArrayList,一个早期的,现已弃用的.NET数据结构,它允许你坚持不同租用对象的类型,但是你在运行时付出了高昂的代价,因为实际使用你所存储的东西需要装箱和拆箱。



更好的做法:创建一个Class(或Struct),如果需要,还可以创建它们的集合。



另外,请注意你的代码是复制功能的从.NET 2.0开始提供的.NET的INotifyPropertyChanging / INotifyPropertyChanged工具。 [ ^ ]。我并不是说这是糟糕的。


Say in MyDelegate.cs

using System;
namespace EventsGeneralExample
{
    public delegate void ChangedEventHandler(object sender, EventArgs e);
}


And in another class ListWithChangedEvent.cs.

namespace EventsGeneralExample
{
    public class ListWithChangedEvent : ArrayList
    {
        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event ChangedEventHandler Changed;      



        // Invoke the Changed event; called whenever list changes
        protected virtual void OnChanged(EventArgs e)
        {
            Console.WriteLine("List has changed, event is firing");
            //Ensure something is subscribed ot it
            if (Changed != null)
                Changed(this, e);
        }

        // Override some of the methods that can change the list;
        // invoke event after each
        public override int Add(object value)
        {
            Console.WriteLine("Adding to the list");
            int i = base.Add(value);
            OnChanged(EventArgs.Empty);
            return i;
        }

        public override void Clear()
        {
            Console.WriteLine("Clearing the list");
            base.Clear();
            OnChanged(EventArgs.Empty);
        }

        public override object this[int index]
        {
            set
            {
                Console.WriteLine("Setting an item on the list");
                base[index] = value;
                OnChanged(EventArgs.Empty);
            }
        }
    }   
}



My question is why we don't need to instance MyDelegate class then declare the event?
Let's say:

MyDelegate my = new MyDelegate();
public event my.ChangedEventHandler Changed;

解决方案

In your class you just declare the event, the actual delegate is provided by the listener. It's the same as declaring a variable, only this one has a bit more semantics to it. It's the same as declaring a variable:

int i;


This says: you can put a int value here. Your class is basically saying: I'm firing this event when some important stuff happens, if you want to get notified provide a delegate and I will call it when the time comes. The ones who want to be notified attach a delegate:

instanceOfListWithChangedEvent.Changed += myDelegate;


Have a look in your OnChnaged() method:

if (Changed != null)
    Changed(this, e);


This is needed because it may happen that nobody is listening and the value fo the delegate is null.

BTW do not name your class ListWithChangedEvent, it is clearly a List!


It is the fact your two Class definitions share the same NameSpace that allows the second Class to use the delegate definition in the first Class: the fact the two Class definitions are in two distinct .cs files ... doesn't matter.

Do be aware that you are using 'ArrayList, an earlier, now deprecated, .NET data-structure which does allow you to stick different Types of objects into it, but you pay a high-cost at run-time because of the required boxing and unboxing of objects required to actually use what you have stored in it.

Better practice: create a Class (or Struct), and a collection of them if needed.

Also, be aware that your code is duplicating the functionality of .NET's INotifyPropertyChanging/INotifyPropertyChanged facilities that were provided beginning with .NET 2.0. [^]. I'm not saying that's "bad."


这篇关于为什么在没有实例化课程的情况下使用委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆