Solution to special problems of. net generic universal Functions

Source: Internet
Author: User

Since the launch of the net framework in version 2.0, Generic (Generic) has been widely praised. It does not have to suffer performance loss like the object type because of "unpacking" or "Packing". At the same time, it can detect in real time whether the incoming or outgoing types meet specific conditions in the compilation syntax detection phase.

But "Gold is bare and nobody is perfect"-while we enjoy these happy programming, uncertainty of the generic type also brings a significant problem-operators cannot be reloaded. For example, what should I do if I want to write a function (a general selection sorting algorithm using generic T? If you simply use such code (C # is as follows ):

Copy codeThe Code is as follows:
// Improved Sorting Algorithm from small to large

Public static void Sort <T> (T [] array)
{
Bool flag = false; // whether the flag has been sorted

For (int I = 0; I <array. Length-1; ++ I)
{
Flag = false; // each time it is assumed that the data has been sorted and no sort is required.

For (int j = I + 1; I <array. Length; ++ j)
{
If (array [I]> array [j])
{
Int temp = array [I];
Array [I] = array [j];
Array [j] = templ
Flag = true; // sorted
}
}
If (! Flag)
{
Break;
}
}
}

After compilation, you will soon find prompts such as "operator"> "cannot act on T.

Why? We know that Operator Overloading is defined for all types that can be greater than or less than the comparison. A general class must be defined for this purpose before comparison can be made. Otherwise, an error occurs because the comparison is not known if the class is greater than or less than the number (or other operators. So what type does the generic model know beforehand? The compiler checker naturally cannot infer that the type that you dynamically pass in during runtime must implement Operator overloading. If you strictly check the syntax, an error is reported.

What should we do? It is required that the generic T must implement the comparator (the mandatory T must implement the IComparable or similar interface ).

Copy codeThe Code is as follows:
Public static void Sort <T> (T [] array) where T: IComparable
{
Bool flag = false; // whether the flag has been sorted

For (int I = 0; I <array. Length-1; ++ I)
{
Flag = false; // each time it is assumed that the data has been sorted and no sort is required.

For (int j = I + 1; I <array. Length; ++ j)
{
If (array [I]. Compare (array [j])> 0)
{
Int temp = array [I];
Array [I] = array [j];
Array [j] = templ
Flag = true; // sorted
}
}
If (! Flag)
{
Break;
}
}
}

Once the generic type is restricted, the generic type must be the class that implements this interface and must have this method (the Compare method returns the int type of the result, if the value is greater than 0, the previous number is greater than the next one ).

Of course, the Microsoft class library has a Comparer static class, has implemented this interface can be directly compared (http://msdn.microsoft.com/zh-cn/library/system.collections.comparer.comparer.aspx), so we can also choose to directly use the Compare method in this static class to get the result.

[Example 2] implement a common "+" -- that is, if the input string is passed in, the character is automatically spliced according to the string; if the input is another basic type (int, double, etc ), returns the result of adding.

Microsoft does not have a pre-defined "+" interface, so it cannot be used directly (of course, you can define a custom interface as required ). Let's change the method -- use the expression tree (C # code is as follows ):

Copy codeThe Code is as follows:
Public static T Add <T> (T a, T B)
{
Expression left = Expression. Constant ();
Expression right = Expression. Constant (B );

Type t = typeof (T );

Expression value;

If (t = typeof (string ))
{
Value = Expression. Constant (a. ToString () + B. ToString ());
}
Else
{
Value = Expression. Add (left, right );
}

Expression <Func <T> addExp = Expression. Lambda <Func <T> (value );

Func <T> addFunc = addExp. Compile ();

Return addFunc ();
}

Dynamically judge whether T is a string or another basic type. Then, call different methods to form an Expression Tree, dynamically compile it into a Func expression, and return the result.

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.