为什么在没有实例化课程的情况下使用委托? [英] Why using delegate without instancing the class?
问题描述
说 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屋!