We will introduce the comparison between C # array sorting and object size, including some instance code and the usage of three interfaces: IComparable, IComparable, and IComparer.
Starting from a small example:
Int [] intArray = new int [] {2, 3, 6, 1, 4, 5}; Array. sort (intArray); Array. forEach <int> (intArray, (I) => Console. writeLine (I); this example defines an int Array, and then uses Array. the Sort (arr) Static Method sorts the array, and finally outputs the sorted array. In the preceding example, output 1, 2, 3, 4, 5, 6 in sequence.
Why can the Array Sort method correctly Sort the int Array? Can we use a custom class? Try the following code:
Public class Student {public int Age {get; set;} public string Name {get; set;} public int Score {get; set ;}} static void Main (string [] args)
{Student [] students = new Student [] {new Student () {Age = 10, Name = "James", Score = 70}, new Student () {Age = 12, name = "Li Si", Score = 97}, new Student () {Age = 11, Name = "Wang Wu", Score = 80}, new Student () {Age = 9, name = "Zhao six", Score = 66}, new Student () {Age = 12, Name = "Sima", Score = 90},}; Console. writeLine ("-- default sorting output --"); Array. sort (students); Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s . Name, s. age, s. score); Console. read ();} we defined the Student class and sorted its arrays. The program was correctly compiled, but an error occurred while running. An exception was thrown: System. invalidOperationException {"Failed to compare two elements in the array. "}, the InnerException of this exception is ArgumentException {" At least one object must implement IComparable. "}; runtime exception description: we need to use Array. the Sort (arr) static method must ensure that an element in the array implements the IComparable interface. In this case, let the Student class implement the IComparable interface.
Public class Student: IComparable {public int Age {get; set;} public string Name {get; set;} public int Score {get; set ;} /// <summary> /// implement the IComparable interface, compare objects with Age /// </summary> /// <param name = "obj"> comparison object </param> /// <returns> comparison result </returns> public int CompareTo (object obj)
{If (obj is Student)
{Return Age. CompareTo (Student) obj ). Age);} return 1;} The IComparable interface is implemented in the Student class, and the Age attribute of Student is compared in the CompareTo method. This time, it is compiled and run again, the program normally outputs the Student array sorted by age.
What if we want to sort the Score attribute of Student? The IComparable interface implemented by the Student class can only be sorted by one attribute.
This is easy to implement. The net class library developer has prepared another IComparer <T> interface for us to implement two instances of the comparison type T. The following StudentScoreComparer class provides IComparer for Student to compare the Score attributes. <Student>
Public class StudentScoreComparer: IComparer <Student> {public int Compare (Student x, Student y)
{Return x. Score. CompareTo (y. Score);} now we can use the following code to sort the Student array by Score attribute:
Console. WriteLine ("-- Sort output by score --");
Array. Sort (students, new StudentScoreComparer ());
Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s. name, s. age, s. score )));
However, it is a little difficult to simply sort by Score attributes and define a class. Is there a better way? Of course. . Net has prepared a Comparison delegate for us to compare the object size. <T> we can use the lambda expression or anonymous delegate for direct sorting. The following code is implemented:
Console. writeLine ("-- sort by score output --"); Array. sort (students, (s1, s2) => s1.Score. compareTo (s2.Score); Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s. name, s. age, s. score). The complete code example is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; namespace SortingInCSharp {class Program {public class Student: IComparable {public int Age {get; set;} public string Name {get; set;} public int Score {get; set ;}//< summary> /// implement the IComparable interface, compare objects with Age /// </summary> /// <param name = "obj"> comparison object </param> /// <returns> comparison result </returns> public int CompareTo (object obj)
{If (obj is Student)
{Return Age. CompareTo (Student) obj ). Age);} return 1;} static void Main (string [] args)
{Student [] students = new Student [] {new Student () {Age = 10, Name = "James", Score = 70}, new Student () {Age = 12, name = "Li Si", Score = 97}, new Student () {Age = 11, Name = "Wang Wu", Score = 80}, new Student () {Age = 9, name = "Zhao six", Score = 66}, new Student () {Age = 12, Name = "Sima", Score = 90},}; Console. writeLine ("-- default sorting output --"); Array. sort (students); Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s. name, s. age, s. score); Console. writeLine ("-- sort by score output --"); Array. sort (students, new StudentScoreComparer (); Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s. name, s. age, s. score); Console. writeLine ("-- sort by score output --"); Array. sort (students, (s1, s2) => s1.Score. compareTo (s2.Score); Array. forEach <Student> (students, (s) => Console. writeLine (string. format ("{0} {1, 2} years old, his score is {2, 3}", s. name, s. age, s. score); Console. read ();} public class StudentScoreComparer: IComparer <Student> {public int Compare (Student x, Student y)
{Return x. Score. CompareTo (y. Score);} summary:
In C #, there are three interfaces for comparing object sizes: IComparable, IComparable <T>, and IComparer <T>. IComparable and IComparable <T> are behavior definitions implemented by the class itself to compare the size between instances. IComparer <T> is a behavior that defines the size of two T-type objects outside the compared class, another delegate definition for Comparison is Comparison <T>, which allows us to use lambda expressions or anonymous delegates or methods for easier sorting.