C # --- view & quot; Delegation and events & quot;

Source: Internet
Author: User

Delegation and events are widely used. I have summarized them for convenience of review.
 
I. Delegation
Delegation, in general, is the 'method' container.
Is used to store and call methods.
 
The following example briefly introduces the delegate usage:
 
[Csharp]
Public delegate void SayHi_Delegate (string name );

This is a delegate. Any function, such as void ** (string **); can be called using this delegate.
For example:
[Csharp]
Private static void SayHiEn (string name) // english description
{
Console. WriteLine ("Hi {0}, I am ZeroCool_24! ", Name );
}
 
Private static void SayHiCh (string name) // speaks Chinese
{
Console. WriteLine ("Hello {0}, I am ZeroCool_24! ", Name );
}

 
The called method is as follows:
[Csharp]
Static void Main (string [] args)
{
SayHi_Delegate Hi;
Hi = SayHiCh;
Hi + = SayHiEn;
 
Hi ("cyh ");
 
Console. ReadLine ();
}
Output result:


We can see that when adding a method to the SayHi method container, we use + =, and we can also use-=; it is worth noting that, the container must have at least one method.
 
We know that methods can be passed as parameters. Similarly, we can also use delegation (method container) as parameters for transmission, as follows:
First, define the function to receive the delegate.
[Csharp]
Private static void GreetPeople (string name, SayHi_Delegate MakeGreeting)
{
MakeGreeting (name );
}
 
Next, call:
 
[Csharp]
Static void Main (string [] args)
{
SayHi_Delegate Hi;
Hi = SayHiCh;
Hi + = SayHiEn;
 
// Hi ("cyh ");
GreetPeople ("cyh", Hi );
 
Console. ReadLine ();
}

The result is the same as above.
Ii. Events
As you have a preliminary understanding of delegation, we will make an improvement in this example.
[Csharp]
Using System;
 
Namespace Delegation
{
Public delegate void SayHi_Delegate (string name );

Public class GreetClass // New class
{
Public void GreetPeople (string name, SayHi_Delegate MakeGreeting)
{
MakeGreeting (name );
}
}
}

 
[Csharp]
Using System;
 
Namespace Delegation
{
Class TestClass
{
Private static void SayHiEn (string name)
{
Console. WriteLine ("Hi {0}, I am ZeroCool_24! ", Name );
}
 
Private static void SayHiCh (string name)
{
Console. WriteLine ("Hello {0}, I am ZeroCool_24! ", Name );
}
 
Static void Main (string [] args)
{
SayHi_Delegate Hi;
Hi = SayHiCh;
Hi + = SayHiEn;
 
// Hi ("cyh ");
GreetClass greet = new GreetClass ();
Greet. GreetPeople ("cyh", Hi );
 
Greet. GreetPeople ("zc", SayHiCh); // SayHiCh () is not a SayHi_Delegate delegate, but can be converted into a delegate containing only SayHiCh () methods.
 
Console. ReadLine ();
}
}
}


The result is as follows:

 
The demo results are good, and it seems that there is no problem. But can it be better handled?
The answer is yes. To apply the object-oriented idea, we should encapsulate the principal variable Hi in main () into the GreetClass class.
[Csharp]
Using System;
 
Namespace Delegation
{
Public delegate void SayHi_Delegate (string name );

Public class GreetClass
{
Public SayHi_Delegate Hi; // SayHi_Delegate instance
 
Public void GreetPeople (string name, SayHi_Delegate MakeGreeting)
{
MakeGreeting (name );
}
}
}
[Csharp]
Static void Main (string [] args)
{
GreetClass greet = new GreetClass ();
Greet. Hi = SayHiCh;
Greet. Hi + = SayHiEn;
 
Greet. GreetPeople ("Cyh_Zc", greet. Hi );
 
Console. ReadLine ();
}

 


In this way, another problem occurs. Although the delegate variable Hi is encapsulated into GreetClass, the client can still access it at will, which brings about a security problem, if the current Hi is not the SayHi_Delegate type, but the string type, we can use the attribute to solve the problem.
But how can we solve the delegate variable?
Yes, it's an event. Event, which encapsulates the variables of the delegate type, so that, inside the class, whether you declare it as public or protected, it is always private. Outside the class, register the "+ =" and logout "-=" Access delimiters with the same access delimiters as you used when declaring an event.
 
Let's rewrite the GreetClass class:
 
[Csharp]
Public class GreetClass
{
Public event SayHi_Delegate Hi; // SayHi_Delegate event, only the modifier adds an event public void GreetPeople (string name)
{
Hi (name );
}
}
[Csharp]
Static void Main (string [] args)
{
GreetClass greet = new GreetClass ();
// Greet. Hi = SayHiCh; // compilation error greet. Hi + = SayHiCh;
Greet. Hi + = SayHiEn;
 
Greet. GreetPeople ("Cyh_Zc ");
 
Console. ReadLine ();
}

 
As you can see, a compilation error occurs when greet. Hi = SayHiCh is used. Why?
In the past, greet. Hi can only appear on the left side of + = or-= (except when used in the class "GreetClass ). Why?
We use. NET Reflector to check the GreetClass compilation process:
[Csharp]
Public class GreetClass
{
// Fields
Private SayHi_Delegate Hi;
 
// Events
Public event SayHi_Delegate Hi;
 
// Methods
Public GreetClass ();
Public void GreetPeople (string name );
}
Seeing the compiled code above, you may wonder why there is an additional (Fields) private SayHi_Delegate Hi;
Originally, the public event SayHi_Delegate Hi; after this line of code is compiled, a private field SayHi_Delegate Hi is automatically added by default;
 
Conjecture: The Hi field of the private SayHi_Delegate type is used in GreetClass, and the Public event Hi is used externally.
Verify: view the Hi (name) in GreetClass );
The reference is:
[Csharp]
Private SayHi_Delegate Hi;
Check greet. Hi in the Main () method. You can see:
[Csharp]
Public event SayHi_Delegate Hi
{
Add
{
SayHi_Delegate delegate3;
SayHi_Delegate hi = this. Hi;
Do
{
Delegate3 = hi;
SayHi_Delegate delegate4 = (SayHi_Delegate) Delegate. Combine (delegate3, value );
Hi = Interlocked. CompareExchange <SayHi_Delegate> (ref this. Hi, delegate4, delegate3 );
}
While (hi! = Delegate3 );
}
Remove
{
SayHi_Delegate delegate3;
SayHi_Delegate hi = this. Hi;
Do
{
Delegate3 = hi;
SayHi_Delegate delegate4 = (SayHi_Delegate) Delegate. Remove (delegate3, value );
Hi = Interlocked. CompareExchange <SayHi_Delegate> (ref this. Hi, delegate4, delegate3 );
}
While (hi! = Delegate3 );
}
}
 
The above conjecture is correct.
There are two methods in event Hi (): add () and remove (). I guess you have already guessed that these two functions correspond to greet. two operations of Hi + = and-=. Now I think you should also know why greet. Hi = SayHiCh; will report an error ------ because the Hi event does not have a method corresponding to '=.
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.