C#语言规范 - 代表 [英] C# Language Specification - Delegates

查看:47
本文介绍了C#语言规范 - 代表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



首先......让我们与代表们打交道。评论欢迎。


1)调用NULL委托很烦人。

**(它应该什么都不做而不是崩溃。)


2)很容易将多个冗余处理程序附加到

代表上。


3)代表可能会指出处理超出范围的对象或处理
导致这些对象崩溃。

**(处理程序应该在定义
他们离开范围)。


4)?

5)?


那里是一种潜在的委托泄密对象附加

处理程序无限期,而处理程序函数被称为每个事件的增加次数

次数...

不幸的是,通往防止上述问题不方便

方便...


因此,对于保护性编码......我们必须真正宣布正确的法律

委托使用情况如下? (我希望我们能解决一个更方便的方式)。


////////////////////////// //////////////////////////////

/////所有与活动相关的课程链接......


//声明此成员变量

System.EventHandler _hEventHandler;


/ /在构造期间:

_hEventHandler = new System.EventHandler(无论如何);


//在初始化期间:

_obj._SomeEvent + = _hEventHandler;


//在处理此期间:(所有用户必须调用Dispose)

_obj._SomeEvent - = _hEventHandler;


/////////////////////////////////////// /////////////////

///////////////////////// ///////////////////////////////

/////所有必须服务的人...

/////////////////////////////////////// /////////////////

公共事件System.EventHandler _SomeEvent

{

add

{

// PR事件相同的处理者不仅仅是附上

附上(ref _eSomeEvent,value);

}

删除

{

_eSomeEvent - = value;

}

}


私人活动系统。 EventHandler _eSomeEvent;


private void _FireSomeEvent()

{

Fire(_eSomeEvent,this,whatever);

}


public static void Fire(System.EventHandler h,object sender,

System.EventArgs args)

{

//在没有空的情况下从事件中保护

if(h!= null)h(sender,args);

}


public static void Attach(ref System.EventHandler h1,System.EventHandler h2)

{

//来自同一个HANDLER的保护添加多个时间

if(h2 == null)return;

if(h1!= null)

{

System.Delegate [] ar = h1.GetInvocationList();

foreach(ar中的System.Delegate dg)if(dg == h2)return;

}

//(当h1为空时这没关系)

h1 + = h2;

}


First... let''s deal with Delegates. Comments welcome.

1) Invoking a NULL delegate is annoying.
** (It should just do nothing rather than crash.)

2) It''s too easy to accidently attach multiple redundant handlers onto
delegates.

3) A delegate might point to handlers on objects that are out of scope or
been disposed, causing those objects to crash.
** (Handlers should be removed automatically when the object that defines
them leaves scope).

4) ?
5) ?

There is sort of a potential for "delegate leak" where objects attach
handlers indefinitely while the handler functions get called an increasing
number of times per event...
Unfortunately, the way to prevent the aforementioned problems is not
convenient...

So, for protective coding... must we truly declare the laws of proper
delegate usage as follows? (I hope we can resolve a more convenient way).

////////////////////////////////////////////////////////
///// ALL CLASSES THAT ATTACH TO THE EVENT CHAIN MUST...

// declare member variable of this
System.EventHandler _hEventHandler;

// during construction of this:
_hEventHandler = new System.EventHandler(whatever);

// during initialization of this:
_obj._SomeEvent += _hEventHandler;

// during disposal of this: (all users must call Dispose)
_obj._SomeEvent -= _hEventHandler;

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///// ALL CLASSES SERVING AN EVENT MUST...
////////////////////////////////////////////////////////
public event System.EventHandler _SomeEvent
{
add
{
// PREVENTS THE SAME HANDLER FROM BEING ATTACHED MORE THAN ONCE
Attach(ref _eSomeEvent, value);
}
remove
{
_eSomeEvent -= value;
}
}

private event System.EventHandler _eSomeEvent;

private void _FireSomeEvent()
{
Fire(_eSomeEvent, this, whatever);
}

public static void Fire(System.EventHandler h, object sender,
System.EventArgs args)
{
// PROTECTS FROM EVENT INVOKED WHEN NULL
if(h!=null) h(sender, args);
}

public static void Attach(ref System.EventHandler h1, System.EventHandler h2)
{
// PROTECTS FROM SAME HANDLER BEING ADDED MULTIPLE TIMES
if(h2==null) return;
if(h1!=null)
{
System.Delegate[] ar = h1.GetInvocationList();
foreach(System.Delegate dg in ar) if(dg == h2) return;
}
// (this is okay when h1 is null)
h1 += h2;
}

推荐答案

" Marshal" <马***** @ discussions.microsoft.com>一个écritdansle message de

新闻: 9E ********* @ microsoft.com ...
"Marshal" <Ma*****@discussions.microsoft.com> a écrit dans le message de
news: 9E**********************************@microsoft.com...
首先......让我们与代表打交道。欢迎评论。

1)调用NULL委托很烦人。
**(它应该什么都不做而不是崩溃。)


调用委托的类应始终在调用它之前检查null。

2)很容易将多个冗余处理程序附加到
代理上。


不是编写良好的代码。

3)代表可能指向处理范围超出范围或处置的对象,造成那些崩溃的对象。
**(处理程序应该在定义它们的对象离开范围时自动删除)。


只要持有事件的类中的委托引用了另一个对象的

方法,那么该另一个对象就不能垃圾收集

并且仍然有效。

有可能出现委托泄密的情况。对象附加处理程序无限期,而处理程序函数被称为每个事件的增加次数...


这在很有礼貌的代码中是不可能的。

不幸的是,防止上述问题的方法并不方便......

因此,对于保护性编码......我们必须真正宣布适当的
委托使用如下? (我希望我们能解决一个更方便的方式)。

////////////////////////////// //////////////////////////
/////所有连接到事件链的类都必须......
//声明这个
System.EventHandler _hEventHandler的成员变量;

//在构造过程中:
_hEventHandler = new System.EventHandler(无论如何);

//初始化期间:
_obj._SomeEvent + = _hEventHandler;

//在处理此期间:(所有用户必须调用Dispose)
_obj._SomeEvent - = _hEventHandler;

///////////////////////////////// ///////////////////////


public delegate void NotificationHandler(object sender);

public class ReceiverClass

{

public void HandleNotification(object sender)

{

... < br $>
}

}


然后创建此类实例的代码也可以附加其

给Sen的处理程序方法der class(参见后面的代码)


void MethodToCreateAndAttachToSender

{

SenderClasssc = new SenderClass();


ReceiverClass rc = new ReceiverClass();


sc.Notify + = new NotificationHandler(rc.HandleNotification)

}

//////////////////////////////////////////// ////////////
/////所有必须服务的人......
//////////////// ////////////////////////////////////////
公共事件System.EventHandler _SomeEvent
{
添加
//防止相同的处理器不仅仅是附加
附件(ref _eSomeEvent,value);
}
删除
{
_SomeEvent - = value;
}

私人活动System.EventHandler _eSomeEvent;

private void _FireSomeEvent()
{Fire(_eSomeEvent,this,whatever);


public static void Fire(System.EventHandler h,object sender,
System.EventArgs args)
{
//在NULL时调用事件
if(h!= null)h(sender,args);
}

public static void Attach(ref System.EventHandler h1,System.EventHandler
h2){
//从同一个处理程序中添加多个时间
如果(h2 == null)返回;
if(h1!= null)
{System /Delegate [] ar = h1.GetInvocationList();
foreach(ar中的System.Delegate dg)if(dg == h2)return;
}
//(当h1为空时这没关系)
h1 + = h2;
}
First... let''s deal with Delegates. Comments welcome.

1) Invoking a NULL delegate is annoying.
** (It should just do nothing rather than crash.)
The class that invokes the delegate should always check for null before
calling it.
2) It''s too easy to accidently attach multiple redundant handlers onto
delegates.
Not in well written code.
3) A delegate might point to handlers on objects that are out of scope or
been disposed, causing those objects to crash.
** (Handlers should be removed automatically when the object that defines
them leaves scope).
As long as the delegate in class that holds the event has a reference to a
method of another object, then that other object can''t be garbage collected
and will remain valid.
There is sort of a potential for "delegate leak" where objects attach
handlers indefinitely while the handler functions get called an increasing
number of times per event...
This is unlikely in well-mannered code.
Unfortunately, the way to prevent the aforementioned problems is not
convenient...

So, for protective coding... must we truly declare the laws of proper
delegate usage as follows? (I hope we can resolve a more convenient way).

////////////////////////////////////////////////////////
///// ALL CLASSES THAT ATTACH TO THE EVENT CHAIN MUST...

// declare member variable of this
System.EventHandler _hEventHandler;

// during construction of this:
_hEventHandler = new System.EventHandler(whatever);

// during initialization of this:
_obj._SomeEvent += _hEventHandler;

// during disposal of this: (all users must call Dispose)
_obj._SomeEvent -= _hEventHandler;

////////////////////////////////////////////////////////
public delegate void NotificationHandler(object sender);
public class ReceiverClass
{
public void HandleNotification(object sender)
{
...
}
}

Then the code that creates an instance of this class can also attach its
handler method to the Sender class (see later code)

void MethodToCreateAndAttachToSender
{
SenderClasssc = new SenderClass();

ReceiverClass rc = new ReceiverClass();

sc.Notify += new NotificationHandler(rc.HandleNotification)
}
////////////////////////////////////////////////////////
///// ALL CLASSES SERVING AN EVENT MUST...
////////////////////////////////////////////////////////
public event System.EventHandler _SomeEvent
{
add
{
// PREVENTS THE SAME HANDLER FROM BEING ATTACHED MORE THAN ONCE
Attach(ref _eSomeEvent, value);
}
remove
{
_eSomeEvent -= value;
}
}

private event System.EventHandler _eSomeEvent;

private void _FireSomeEvent()
{
Fire(_eSomeEvent, this, whatever);
}

public static void Fire(System.EventHandler h, object sender,
System.EventArgs args)
{
// PROTECTS FROM EVENT INVOKED WHEN NULL
if(h!=null) h(sender, args);
}

public static void Attach(ref System.EventHandler h1, System.EventHandler h2) {
// PROTECTS FROM SAME HANDLER BEING ADDED MULTIPLE TIMES
if(h2==null) return;
if(h1!=null)
{
System.Delegate[] ar = h1.GetInvocationList();
foreach(System.Delegate dg in ar) if(dg == h2) return;
}
// (this is okay when h1 is null)
h1 += h2;
}




这是过度的,没有必要;如果您按照指令设置

将多播代表作为一个事件,那么您需要做的就是

以下内容:


public delegate void NotificationHandler(object sender);

public class SenderClass

{

private void OnNotify(object someObject)

{

if(Notify!= null)

通知(someObject);

}

公共事件NotificationHandler通知;


public void SomeMethodThatNeedsToInvokeEvent

{

//进行更改

OnNotify(this);

}


为什么你认为你需要所有额外的代码?


Joanna


-

Joanna Carter

顾问软件工程师



This is overkill and not necessary; if you follow the guidelines for setting
up a multicast delegate as an event, then all you need to do is the
following :

public delegate void NotificationHandler(object sender);
public class SenderClass
{
private void OnNotify(object someObject)
{
if (Notify != null)
Notify(someObject);
}

public event NotificationHandler Notify;

public void SomeMethodThatNeedsToInvokeEvent
{
// make changes
OnNotify(this);
}

Why do you think you need all that extra code ??

Joanna

--
Joanna Carter
Consultant Software Engineer


2005-09-18,Joanna Carter(TeamB)< jo ***** @ nospamforme.com>写道:
On 2005-09-18, Joanna Carter (TeamB) <jo*****@nospamforme.com> wrote:
" Marshal" <马***** @ discussions.microsoft.com> écritdansle message de
新闻: 9E ********************************** @ microsoft.com ...
"Marshal" <Ma*****@discussions.microsoft.com> a écrit dans le message de
news: 9E**********************************@microsoft.com...
首先......让我们与代表打交道。欢迎评论。

1)调用NULL委托很烦人。
**(它应该什么都不做而不是崩溃。)
First... let''s deal with Delegates. Comments welcome.

1) Invoking a NULL delegate is annoying.
** (It should just do nothing rather than crash.)



调用委托的类应该在调用它之前检查null。



The class that invokes the delegate should always check for null before
calling it.




嗯,显然海报知道这是因为他建议

行为*应该*不同。



Well, obviously the poster is aware of that since he''s suggesting the
behavior *should* be different.


" david" <哒*** @ woofix.local.dom> écritdansle message de news:
sl ***** *************@localhost.loca ldomain ...
"david" <da***@woofix.local.dom> a écrit dans le message de news:
sl******************@localhost.localdomain...
嗯,显然海报知道这一点,因为他''建议
行为*应该*不同。
Well, obviously the poster is aware of that since he''s suggesting the
behavior *should* be different.




由于调用任何null对象上的任何方法都会失败,我想要

强调任何其他行为都是不可能的。 OP似乎是
,这使得一个简单的原则变得不必要地复杂化。


Joanna


-

Joanna Carter

顾问软件工程师



Since invoking any method on any null object will fail, I wanted to
reinforce that any other behaviour was not possible. The OP seems to be
making a simple principle unnecessarily complicated.

Joanna

--
Joanna Carter
Consultant Software Engineer


这篇关于C#语言规范 - 代表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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