In C #2.0, the cooperation between anonymous methods, IEnumerable interfaces, and anonymous methods makes many programming tasks very simple and the programs written are very beautiful.
For example, we can write the following code:
List <Book> thelib = Library. getbooks ();
List <Book> found = thelib. FindAll (delegate (Book curbook) { If (curbook. isbn. StartsWith ("...")) Return true; Return false; });
Foreach (Book B in found) Console. WriteLine (B. isbn ); |
This program is very simple to show us the information we need to find, and the code is very straightforward. The built-in data structure provides us with powerful algorithm support. However, can we define similar algorithms for custom classes?
For example, if I have a custom Library class that does not use List <Book> to store data, but uses a custom data structure, I can make users use similar syntaxes, what if anonymous delegation is used to implement specific algorithms that ignore storage details?
The answer is of course yes, and it is very simple to implement such a function in C.
First, let's look at the prototype of anonymous delegation used in FindAll.
Public delegate bool Predicate <T> (T obj );
Obviously, the code above is equivalent to registering a search callback, and a traversal mechanism is defined inside the List to implement a beautiful algorithm structure Closure.
Once we see this, we can define our own algorithm structure. First, I define the following class
Public class MyVec <T> { Public static MyVec <T> operator + (MyVec <T> a, T B) { A. _ list. Add (B ); Return; } Public override string ToString () { StringBuilder builder = new StringBuilder (); Foreach (T a in _ list) { Builder. Append (a. ToString ()); Builder. Append (","); } String ret = builder. Remove (builder. Length-1, 1). ToString (); Return ret; }
Public MyVec <T <> findAll (Predicate <T> act) { MyVec <T:> t2 = new MyVec <T> (); Foreach (T I in _ list) { If (act (I )) T2. _ list. Add (I ); } Return t2; }
// This is the inner object Private List <T> _ list = new List <T> (); } |
This class contains a List <T> structure, mainly to verify whether our ideas are feasible. In fact, any structure that supports foreach traversal can be used as a built-in data storage object. We will give a more complex implementation in the following example.
The following code is used to test the experiment class:
Static void Main (string [] args) { MyVec <int> a = new MyVec <int> (); A + = 12; A + = 15; A + = 32; MyVec <int> B = a. findAll (delegate (int x) { If (x <20) return true; return false; } );
Console. WriteLine ("vection original "); Console. WriteLine (a. ToString ()); Console. WriteLine ("vection found "); Console. WriteLine (B. ToString ()); Console. ReadLine (); } |
Compile, execute, and program output:
Vection original
12, 15, 32
Vection found
32 |
It is exactly the same as we expected. Obviously, the algorithms inside the List are basically the same as we expected.
Predicate <T> is only a delegate used to follow the implementation of the system. In fact, you can use any delegate defined by yourself as the callback function body.
You can use the IEnumberable interface to traverse any structure and define powerful algorithms for any data structure.