In the. NET generics 01, why generics are required, generic basic syntax ", understand the basic concepts of generics, this article emphasizes the use of generics. Mainly include:
Problems needing attention in generic method overloading
Type inference for generics
Generic methods can also have constraints
Generic interface
Generic delegate
Using the Eventhandler<teventargs> event generics
Problems needing attention in generic method overloading
Public classMyarray<t>{ PublicT MyData; PublicMyArray () {MyData=default(T); } Public voidShowinfo () {Console.WriteLine (mydata.tostring ()); } Public voidShowinfo (stringstr) {Console.WriteLine (str); } Public voidShowinfo<t>(T data) {Console.WriteLine (data. ToString ()); }}
Above, Description: The generic method can be overloaded as a method.
This can be called.
New Myarray<student>(); Myarray.showinfo<CollegeStudent> (new collegestudent ()); Myarray.showinfo<string> ("HelloWorld");
However, there is another case: two overloaded methods with unknown semantics are passed at compile time, but they do not pass at the time of the call. For example, the following is not a problem at compile time:
Public class Myarray<t>{ publicvoid showinfo<ta, tb>(TA A, TB b) {}; Public void SHOWINFO<TB, ta>(TA A, TB b) {};}
If this is called, there is a problem:
New Myarray<student>(); Myarray.showinfo<student, student> (newnew Student ());
Therefore, for generic overloaded methods, you need to pay attention to the situation of unknown semantics.
Type inference for generics
The compiler can infer which overloaded method to use based on the type of the method parameter, prioritize the general overloaded method, and then call the generic overloaded method.
Myarray.showinfo ("hello"); The Showinfo (string str) overloaded method Myarray.showinfo (new collegestudent ()) is called, and the showinfo<t is called > (T Data) overloaded method.
Generic methods can also have constraints
We know that generic classes can have constraints, as are generic methods.
Public void Showinfo<t> (T data) where tdata:student{ Console.WriteLine (data. ToString ());}
Generic interface
. NET collection classes provide multiple generic interfaces, such as: Ilist<t>, Icollection<t>, Icomparable<>, Icomparer<t>, ienumerable< T>, Ienumerator<t>, idictionary<tkey,tvalue>, et cetera.
When customizing a class, it is sometimes necessary to have a custom class implement a generic interface that specifies a specific type:
class Myclass<t>: Icomparable<int32>, icomparable<string>
Generic delegate
Public classGeneric delegate{//declaring generic Delegates Public Delegate stringMygenericdelegate<t>(T T); Public Static stringGetPoint (point p) {returnStirng. Format ("the address is {0},{1}", p.x, P.Y); } Public Static stringGetmsg (stringstr) { returnstr; }} Public Static voidMain () {mygenericdelegate<string> Mystrdel =Newmygenericdelegate<string>(getmsg); Console.WriteLine (Mystrdel ("Hello")); Mygenericdelegate<Point> Mypointdel =NewMygenericdelegate<point>(GetPoint); Console.WriteLine (Mypointdel (NewPoint ( -, $)));}
Using the Eventhandler<teventargs> event generics
The complete definition of this is:
Public Delegate void Eventhandler<teventargs> (objectwhere Teventargs:eventargs
Suppose there is a messagereceiver class that triggers the onconnected event when a connection is established, and the message is triggered when the Onmessagereceived event is received.
Before creating the Messagereceiver class, we will first customize a class that is derived from EventArgs and that is related to Messagereceiver.
Public Sealed class messagereceivedeventargs:eventargs{ publicstring Message {get; Set;} Public Messagereceivedeventargs (string msg) { this. Message = msg;} }
The Messagereceiver class consists of 2 events, one is the onconnected event and the other is the Onmessagereceived event.
public class messagereceiver{ public event EventHandler onconnected; public event eventhandler< Messagereceivedeventargs> onmessagereceived; ... public void Dosth () { if (onmessagereceived! = null ) {onmessagereceived ( this , new Messagereceivedeventargs (msg)); } }}
Above, through if (onmessagereceived! = null) This judgment, can guarantee: when there is no subscriber registration event, this event is not triggered. In a multithreaded scenario, however, this is not the most logical thing to do:
Assuming that thread a registers an event as a subscriber and is preparing to trigger an event, thread B also logs off the event as a subscriber just now, that is, onmessagereceived becomes null, which tie to thread A and cannot trigger the event.
The workaround is to assign the event variable to a local variable:
Public classmessagereceiver{ Public EventEventHandler onconnected; Public EventEventhandler<messagereceivedeventargs>onmessagereceived; ... Public voiddosth () {varHandler =onmessagereceived; if(Handler! =NULL) {Handler ( This,NewMessagereceivedeventargs (msg)); } }}
In this way, when thread A is registered as a subscriber and ready to trigger events, thread B is logged off at this moment and onmessagereceived is null, and thread A can trigger the event because the onmessagereceived has been assigned to the local variable handler.
Resources:
You must know. NET (2nd edition), author Wang Tao.
". NET GENERIC "series includes:
. NET generics 01, why generic, generic basic syntax is required. NET generics 02, the use of generics