C # advanced programming (2)-proxy

Source: Internet
Author: User

Essentially, a proxy provides method encapsulation. It encapsulates a method in a proxy object in a certain way and uses the proxy object to call methods, remove or add proxy objects. In another sense, you can regard the proxy type as the interface of a single method, and the proxy object as the object that implements the interface.
Basic proxy object: proxy type
The following code defines a proxy type
[Csharp]
Internal delegate void Feedback (Int32 value );

C # the compiler actually converts this proxy type into a class inherited from MulticastDelegate.
[Csharp]
Internal class Feedback: System. MulticastDelegate
{
// Constructor
Public Feedback (Object object, IntPtr method );
// Method with same prototype as specified by the source code
Public virtual void Invoke (Int32 value );
// Methods allowing the callback to be called asynchronously
Public virtual IAsyncResult BeginInvoke (Int32 value,
AsyncCallback callback, Object object );
Public virtual void EndInvoke (IAsyncResult result );
}
MulticastDelegate inherits from the Delegate class. The following is the proxy class signature:
[Csharp]
Public abstract class Delegate: ICloneable, ISerializable
{
Protected Delegate (object target, string method );
Protected Delegate (Type target, string method );
 
Public static bool operator! = (Delegate d1, Delegate d2 );
Public static bool operator = (Delegate d1, Delegate d2 );
 
Public MethodInfo Method {get ;}
Public object Target {get ;}
 
Public virtual object Clone ();
Public static Delegate Combine (params Delegate [] delegates );
Public static Delegate Combine (Delegate a, Delegate B );
Protected virtual Delegate CombineImpl (Delegate d );
Public static Delegate CreateDelegate (Type type, MethodInfo method );
Public static Delegate CreateDelegate (Type type, MethodInfo method, bool throwOnBindFailure );
Public static Delegate CreateDelegate (Type type, object firstArgument, MethodInfo method );
Public static Delegate CreateDelegate (Type type, object target, string method );
Public static Delegate CreateDelegate (Type type, Type target, string method );
Public static Delegate CreateDelegate (Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure );
Public static Delegate CreateDelegate (Type type, object target, string method, bool ignoreCase );
Public static Delegate CreateDelegate (Type type, Type target, string method, bool ignoreCase );
Public static Delegate CreateDelegate (Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure );
Public static Delegate CreateDelegate (Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure );
Public object DynamicInvoke (params object [] args );
Protected virtual object DynamicInvokeImpl (object [] args );
Public override bool Equals (object obj );
Public override int GetHashCode ();
Public virtual Delegate [] GetInvocationList ();
Protected virtual MethodInfo GetMethodImpl ();
Public virtual void GetObjectData (SerializationInfo info, StreamingContext context );
Public static Delegate Remove (Delegate source, Delegate value );
Public static Delegate RemoveAll (Delegate source, Delegate value );
Protected virtual Delegate RemoveImpl (Delegate d );
}

This conversion actually defines all possible operations on the proxy object, which will be listed one by one below
1. Construct and initialize proxy objects
The most common method is to use the following method to construct and initialize proxy objects.
[Csharp]
Feedback fbInstance = new Feedback (new Program (). FeedbackToFile );

However, with the upgrade of C #, more and more proxy-related features are introduced, and the proxy Object Construction and initialization methods are also changed, for example, in C #3.0, you can use anonymous methods or lambda expressions to construct and initialize proxy objects.
2. Call the proxy object Encapsulation Method
This is actually the Invoke or BeginInvoke method generated by the compiler when calling the proxy definition. One is used for Synchronous calls, and the other is used for asynchronous calls.
[Csharp]
FbInstance. Invoke (1 );

However, C # performs further optimization. You can directly call the encapsulated method through the proxy object, for example:
[Csharp]
FbInstance (1 );

3. Connect and remove proxy objects
The proxy object we saw earlier encapsulates a method. In fact, the proxy object can encapsulate a series of methods into a linked list. This feature depends on the Combine and Remove methods of the Delegate class.
[Csharp]
FbChain = (Feedback) Delegate. Combine (fbChain, fb1 );

In fact, C # provides Optimization for this usage. You can use the +, ++ =,-, and-= operators to add or remove proxy objects:
[Csharp]
FbChain + = fb1;

Proxy Extension: Event
C # The introduction of events is similar to the introduction of properties. properties are the encapsulation of fields, and event objects are the encapsulation of proxy objects.
When the following events are defined:
[Csharp]
Public event EventHandler <NewMailEventArgs> NewMail;

C # the compiler will actually convert it into the following code:
[Csharp]
// 1. a private delegate field that is initialized to null
Private EventHandler <NewMailEventArgs> NewMail = null;
// 2. a public add_Xxx method (where Xxx is the Event name)
// Allows methods to register interest in the event.
Public void add_NewMail (EventHandler <NewMailEventArgs> value ){
// The loop and the call to CompareExchange is all just a fancy way
// Of adding a delegate to the event in a thread-safe way
EventHandler <NewMailEventArgs> prevHandler;
EventHandler <NewMailEventArgs> newMail = this. NewMail;
Do {
PrevHandler = newMail;
EventHandler <NewMailEventArgs> newHandler =
(EventHandler <NewMailEventArgs>) Delegate. Combine (prevHandler, value );
NewMail = Interlocked. CompareExchange <EventHandler <NewMailEventArgs> (
Ref this. NewMail, newHandler, prevHandler );
} While (newMail! = PrevHandler );
}
// 3. a public remove_Xxx method (where Xxx is the Event name)
// Allows methods to unregister interest in the event.
Public void remove_NewMail (EventHandler <NewMailEventArgs> value ){
// The loop and the call to CompareExchange is all just a fancy way
// Of removing a delegate from the event in a thread-safe way
EventHandler <NewMailEventArgs> prevHandler;
EventHandler <NewMailEventArgs> newMail = this. NewMail;
Do {
PrevHandler = newMail;
EventHandler <NewMailEventArgs> newHandler =
(EventHandler <NewMailEventArgs>) Delegate. Remove (prevHandler, value );
NewMail = Interlocked. CompareExchange <EventHandler <NewMailEventArgs> (
Ref this. NewMail, newHandler, prevHandler );
} While (newMail! = PrevHandler );
}

The code generated above shows that the event object encapsulates the proxy object in the class, and only the add_xxx and remove_xxx methods are exposed (the event object's + = and-= call the corresponding method ), the outside world cannot perform additional operations on its encapsulated proxy objects (build and initialize proxy objects and call proxy object encapsulation methods ).

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.