使用字典存儲事件實例
Accessor-declarations 的一種用法是公開很多事件但不為每個事件分配字段,而是使用字典來存儲這些事件實例。這只在具有很多事件但您預計大多數事件都不會實現時才有用。
public
delegate
void
EventHandler1(
int
i);
public
delegate
void
EventHandler2(
string
s);
public
class
PropertyEventsSample
{
private
System.Collections.Generic.Dictionary<
string
, System.Delegate> eventTable;
public
PropertyEventsSample()
{
eventTable =
new
System.Collections.Generic.Dictionary<
string
, System.Delegate>();
eventTable.Add(
"Event1"
,
null
);
eventTable.Add(
"Event2"
,
null
);
}
public
event
EventHandler1 Event1
{
add
{
lock
(eventTable)
{
eventTable[
"Event1"
] = (EventHandler1)eventTable[
"Event1"
] + value;
}
}
remove
{
lock
(eventTable)
{
eventTable[
"Event1"
] = (EventHandler1)eventTable[
"Event1"
] - value;
}
}
}
public
event
EventHandler2 Event2
{
add
{
lock
(eventTable)
{
eventTable[
"Event2"
] = (EventHandler2)eventTable[
"Event2"
] + value;
}
}
remove
{
lock
(eventTable)
{
eventTable[
"Event2"
] = (EventHandler2)eventTable[
"Event2"
] - value;
}
}
}
internal
void
RaiseEvent1(
int
i)
{
EventHandler1 handler1;
if
(
null
!= (handler1 = (EventHandler1)eventTable[
"Event1"
]))
{
handler1(i);
}
}
internal
void
RaiseEvent2(
string
s)
{
EventHandler2 handler2;
if
(
null
!= (handler2 = (EventHandler2)eventTable[
"Event2"
]))
{
handler2(s);
}
}
}
public
class
TestClass
{
public
static
void
Delegate1Method(
int
i)
{
System.Console.WriteLine(i);
}
public
static
void
Delegate2Method(
string
s)
{
System.Console.WriteLine(s);
}
static
void
Main()
{
PropertyEventsSample p =
new
PropertyEventsSample();
p.Event1 +=
new
EventHandler1(TestClass.Delegate1Method);
p.Event1 +=
new
EventHandler1(TestClass.Delegate1Method);
p.Event1 -=
new
EventHandler1(TestClass.Delegate1Method);
p.RaiseEvent1(2);
p.Event2 +=
new
EventHandler2(TestClass.Delegate2Method);
p.Event2 +=
new
EventHandler2(TestClass.Delegate2Method);
p.Event2 -=
new
EventHandler2(TestClass.Delegate2Method);
p.RaiseEvent2(
"TestString"
);
// Keep the console window open in debug mode.
System.Console.WriteLine(
"Press any key to exit."
);
System.Console.ReadKey();
}
}
輸出:
2
TestString
實現自定義事件訪問器
事件是特殊類型的多路廣播委托,只能從聲明它的類中調用。客戶端代碼通過提供對應在引發事件時調用的方法的引用來訂閱事件。這些方法通過事件訪問器添加到委托的調用列表中,事件訪問器類似於屬性訪問器,不同之處在於事件訪問器被命名為 add 和 remove。在大多數情況下都不需要提供自定義的事件訪問器。如果您在代碼中沒有提供自定義的事件訪問器,編譯器會自動添加事件訪問器。但在某些情況下,您可能需要提供自定義行為。下面的示例演示如何實現自定義的 add 和 remove 事件訪問器。雖然可以替換這些訪問器內的任何代碼,但建議您在添加或移除新的事件處理程序方法之前先鎖定該事件。
event
EventHandler IDrawingObject.OnDraw
{
add
{
lock
(PreDrawEvent)
{
PreDrawEvent += value;
}
}
remove
{
lock
(PreDrawEvent)
{
PreDrawEvent -= value;
}
}
}