Design Pattern in. NET Framework -- Application policy pattern is sorted by List

Source: Internet
Author: User

Sorting is common during programming. net is the most common sorting of the generic List <T>. If T is a simple sorting of data types, you can directly call the Sort () method of the List, but what if the objects to be sorted are complicated? We know that List <T> sort () is implemented by fast sorting and fast sorting, you need to know the comparison results between items in the list. If it is a simple int type, you can directly judge it. For objects that implement the IComparable interface, you can call its CompareTo () compare the size of items. The following is a quick sorting method.


Void Sort <T> (T [] array, int left, int right, IComparer_sly <T> comparer) where T: IComparable
{
If (left <right)
{
T middle = array [(left + right)/2];
Int I = left-1;
Int j = right + 1;
While (true)
{
While (array [++ I]. CompareTo (middle) <0 );

While (array [-- j]. CompareTo (middle)> 0 );

If (I> = j)
Break;

T temp = array [I];
Array [I] = array [j];
Array [j] = temp;
}

Sort (array, left, I-1, comparer );
Sort (array, j + 1, right, comparer );
}
}

 

 

Problem

The first two cases can be sorted, but we cannot require all objects to be sorted to implement the IComparable interface. Even if each object can implement the IComparable interface, if you want to sort multiple fields in an object, such as a Student object, you sometimes want to sort by name, sometimes by score, or sometimes by age, how can this problem be solved?

According to the object-oriented thinking, we need to separate the changes and encapsulate the changes. What changes occur when we sort the List <T> is how to compare the size of the two objects, if we can take this algorithm out, sorting will be much simpler. No matter what sort, the algorithm is from. What we want to encapsulate is how to compare the size of two items, to achieve scalability, we need to follow another important principle of object-oriented design, for interface programming, rather than for implementation programming.

Compile a general List <T> sorting method first defines an interface, which has a method that compares the item size. It is passed as a parameter during sorting, and of course its implementation class, with this idea, we can write a List <T> sorting method by ourselves.

Public interface IComparer_sly <T> {
Int Compare (T x, T y );
}

 

Then, in order to test, we add a package for the List <T> and write our own Sort method, which is also implemented by fast sorting internally. We are always confused about our change part-compare the size algorithm, and we will block it and pass it as a parameter


Using System;
Using System. Collections. Generic;

Namespace Test. Stategy
{Public class ListTest <T>
{
Public List <T> list = new List <T> ();
Public void Sort (IComparer_sly <T> comparer)
{
T [] array = list. ToArray ();
Int left = 0;
Int right = array. Length-1;
QuickSort (array, left, right, comparer );
List = new List <T> (array );
}

Private void QuickSort <S> (S [] array, int left, int right, IComparer_sly <S> comparer)
{
If (left <right)
{
S middle = array [(left + right)/2];
Int I = left-1;
Int j = right + 1;
While (true)
{
While (comparer. Compare (array [++ I], middle) <0 );

While (comparer. Compare (array [-- j], middle)> 0 );

If (I> = j)
Break;

S temp = array [I];
Array [I] = array [j];
Array [j] = temp;
}

QuickSort (array, left, I-1, comparer );
QuickSort (array, j + 1, right, comparer );
}
}
}
} For example, we now have a Student entity.


Public class Student
{
Public Student (int id, string name)
{
This. ID = id;
This. Name = name;
}
Public int ID {get; set ;}
Public string Name {get; set ;}
} If you want to sort the List <T> composed of this object, you only need a class studentcompararer that implements IComparer_sly <Student>, and implement the Compare () method internally (), at the same time, we can add the increment or decrease sort control.


Class StudentComparer: IComparer_sly <Student>
{
Private string expression;
Private bool isAscending;
Public StudentComparer (string expression, bool isAscending)
{
This. expression = expression;
This. isAscending = isAscending;
}

Public int Compare (Student x, Student y)
{
Object v1 = GetValue (x), v2 = GetValue (y );
If (v1 is string | v2 is string)
{
String s1 = (v1 = null )? "": V1.ToString (). Trim ());
String s2 = (v2 = null )? "": V2.ToString (). Trim ());
If (s1.Length = 0 & s2.Length = 0)
Return 0;
Else if (s2.Length = 0)
Return-1;
Else if (s1.Length = 0)
Return 1;
}

// Here, the system method is called, which is not implemented by yourself. In fact, it is difficult to compare the sizes of two data types that are of the same type.
If (! IsAscending)
Return Comparer. Default. Compare (v2, v1 );
Return Comparer. Default. Compare (v1, v2 );
}

Private object GetValue (Student stu)
{
Object v = null;
Switch (expression)
{
Case "id ":
V = stu. ID;
Break;
Case "name ":
V = stu. Name;
Break;
Default:
V = null;
Break;
}
Return v;
}
} Test whether to enable


Static void Main (string [] args)
{
ListTest <Student> test = new ListTest <Student> ();
For (int I = 0; I <10; I ++)
{
Student stu = new Student (I, string. Format ("N _" + (9-i )));
Test. list. Add (stu );
}
Console. WriteLine ("metadata ");
For (int I = 0; I <test. list. Count; I ++)
{
Console. writeLine (string. format ("ID: {0}, Name: {1}", test. list [I]. ID, test. list [I]. name ));
}

Console. WriteLine ("increasing Name ");
Test. Sort (new StudentComparer ("name", true ));
For (int I = 0; I <test. list. Count; I ++)
{
Console. writeLine (string. format ("ID: {0}, Name: {1}", test. list [I]. ID, test. list [I]. name ));
}
} Check the effect

 

 

 

. How to sort the sort of NET List by ILSpy decompilation. We can see this when the sort () method of List <T> is called internally. sort (0, this. count, null); and then dig into it, after a series of exception processing will call Array. sort <T> (this. _ items, index, count, comparer); this. _ items converts the List content to an array. It also goes through some column Exception Processing and calls the ArraySortHelper method. <T>. default. sort (array, index, length, comparer); it is similar to the method we wrote above, but Microsoft adds a lot of Exception Processing and algorithm optimization.

After reading the above example, we can go to the topic and talk about our policy model. Policy patterns define a series of algorithms, encapsulate each algorithm, and make them replaceable. The rule mode allows algorithms to change independently of customers who use it. (Original article: The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it .)

 

This mode involves three roles:

• Context Role: Hold a reference to the Strategy class.
• Strategy role: an abstract role, usually implemented by an interface or abstract class. This role provides all the interfaces required for specific policy classes.
• ConcreteStrategy role: encapsulates related algorithms or behaviors.
I believe that you can easily map the class in the above example to the role in the policy mode. The IComparer interface is our abstract policy role, the ListTest <T> class holds an abstract policy reference as an environment (in the Sort method, you can actually define an interface as a Class Attribute and assign a value to the constructor, but it is not suitable for this scenario, after all, not all lists need to be sorted and cannot be forced to accept an interface that may not be used. Of course, it is appropriate for each instance to use a certain policy ), undoubtedly, the class that implements the IComparer abstract policy is the specific policy.

 

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.