Perception:I have a basic understanding of generic delegation, but I have never really used it in projects. Sometimes I feel that there are no suitable application scenarios, but I have readArticleI realized that the original generic delegation can do a lot of things, and the effect is often not achieved by the use of delegation.
Action <t> generic delegation:Encapsulate a method that uses only one parameter and does not return a value. You can use this delegate to pass methods as parameters without explicitly declaring custom delegates. This method must correspond to the method signature defined by this delegate. That is to say, the encapsulated method must have a parameter passed to it through a value and cannot return a value. Of course, generic delegation not only supports one parameter, but also supports up to four parameters.
Comparison between generic delegation and direct display of custom delegation:
1: display the Declaration custom delegate: Code Delegate Void Displaymessage ( String Message );
Public Class Testcustomdelegate
{
Public Static Void Main ()
{
Displaymessage messagetarget;
Messagetarget = Showwindowsmessage;
Messagetarget ( " Hello, world! " );
}
Private Static Void Showwindowsmessage ( String Message)
{
MessageBox. Show (Message );
}
}
2: Action <t> usage. Compared with custom delegation, we can see that Code Concise. Code Public Class Testaction1
{
Public Static Void Main ()
{
Action < String > Messagetarget;
Messagetarget = Showwindowsmessage;
Messagetarget ( " Hello, world! " );
}
Private Static Void Showwindowsmessage ( String Message)
{
MessageBox. Show (Message );
}
}
Func <t, tresult> delegate:Encapsulate a method that has a parameter and returns the type value specified by the tresult parameter. Similarly, the generic delegate only accepts a parameter delegate. It supports up to four parameters. Tresult: Type of the return value of the method encapsulated by this delegate.
Problem:Currently, the company is writingProgramLog4net is used. I think you will use try catch to catch exceptions, and the logs will be completed in the Catch Block, however, writing a bunch of try-catch statements in each method is often a little awkward. Although we recommend that you try to catch specific error exceptions when writing a program, it is always a good practice to catch exceptions directly because of unexpected exceptions.
Specific scenarios:When the client calls the WCF Service, we need to handle exceptions in the client. The most common error exceptions are communicationexception and timeoutexception. The exception example is as follows:
Code Try
{
// Invocation method call
......
(Proxy As Icommunicationobject). Close ();
}
Catch (Communicationexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " The hotel data on the home page of point Plaza is abnormal. communicationexception: " + Ex. tostring ());
}
Catch (Timeoutexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " Hotel data timeout timeoutexception on the home page of point Plaza: " + Ex. tostring ());
}
Catch (Exception ex)
{
(Proxy As Icommunicationobject). Close ();
Weblog. squarelog. commonlogger. Error ( " An exception occurred while retrieving the hotel data on the home page of point Plaza: " + Ex. tostring ());
}
However, if the code is distributed across the entire project, I think it is necessary to refactor it, because it is best not to have code similar to replication in the project, for this reason, we can use the invoke form to reconstruct our existing code. The following two methods are provided: one with no return value and the other with a value.
Code Public Static Void Invoke < Tcontract > (Tcontract proxy, Action < Tcontract > Action)
{
Try
{
Action (proxy );
(Proxy As Icommunicationobject). Close ();
}
Catch (Communicationexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " The hotel data on the home page of point Plaza is abnormal. communicationexception: " + Ex. tostring ());
}
Catch (Timeoutexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " Hotel data timeout timeoutexception on the home page of point Plaza: " + Ex. tostring ());
}
Catch (Exception ex)
{
(Proxy As Icommunicationobject). Close ();
Weblog. squarelog. commonlogger. Error ( " An exception occurred while retrieving the hotel data on the home page of point Plaza: " + Ex. tostring ());
}
}
Public Static Treturn invoke < Tcontract, treturn > (Tcontract proxy, func < Tcontract, treturn > Func)
{
Treturn returnvalue = Default (Treturn );
Try
{
Returnvalue = Func (proxy );
}
Catch (Communicationexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " The hotel data on the home page of point Plaza is abnormal. communicationexception: " + Ex. tostring ());
}
Catch (Timeoutexception ex)
{
(Proxy As Icommunicationobject). Abort ();
Weblog. squarelog. commonlogger. Error ( " Hotel data timeout timeoutexception on the home page of point Plaza: " + Ex. tostring ());
}
Catch (Exception ex)
{
Weblog. squarelog. commonlogger. Error ( " An exception occurred while retrieving the hotel data on the home page of point Plaza: " + Ex. tostring ());
}
Return Returnvalue;
}
How to call:It can be seen that the client code has become a concise code, which completes the complete Exception Handling and records all the exception information that can be captured.
List = Errorhandler. Invoke < Isearchshortforsquare, list < Hotelgenericinfo > (CLI, proxy => Proxy. getaskgenericlistforsquare (requestinfo). tolist ());
Note:For invoke applications. runtime. remoting. proxies has a realproxy that can be called a real proxy, which contains iMessage invoke (system. runtime. remoting. messaging. iMessage MSG) method: however, no generic delegation is applied.
Code // Returned results:
// The message returned by the invoked method, containing the return value and
// Any out or ref parameters.
Public Abstract IMessage invoke (iMessage MSG );