We often use the List <model> generic type to encapsulate data, but sometimes you may need to sort the generic type under certain requirements, the sorting rules are sorted by a certain attribute in the model. What should I do ?!!
At this time, we need to expand a sorting method by ourselves. Below I will give a class inherited from the IComparer interface, which has built-in sorting rules for ascending and descending order:
[Csharp]
/// <Summary>
/// Inherit from the IComparer <T> interface to compare objects of the same custom type
/// </Summary>
/// <Typeparam name = "T"> T is a generic type </typeparam>
Public class Reverser <T>: IComparer <T>
{
Private Type type = null;
Private ReverserInfo info;
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "type"> comparison class type </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (Type type, string name, ReverserInfo. Direction direction)
{
This. type = type;
This.info. name = name;
If (direction! = ReverserInfo. Direction. ASC)
This.info. direction = direction;
}
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "className"> name of the class to be compared </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (string className, string name, ReverserInfo. Direction direction)
{
Try
{
This. type = Type. GetType (className, true );
This.info. name = name;
This.info. direction = direction;
}
Catch (Exception e)
{
Throw new Exception (e. Message );
}
}
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "t"> compare instances </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (T t, string name, ReverserInfo. Direction direction)
{
This. type = t. GetType ();
This.info. name = name;
This.info. direction = direction;
}
// Required! Compare the implementation of IComparer <T>.
Int IComparer <T>. Compare (T t1, T t2)
{
Object x = this. type. InvokeMember (this.info. name, BindingFlags. Public | BindingFlags. Instance | BindingFlags. GetProperty, null, t1, null );
Object y = this. type. InvokeMember (this.info. name, BindingFlags. Public | BindingFlags. Instance | BindingFlags. GetProperty, null, t2, null );
If (this.info. direction! = ReverserInfo. Direction. ASC)
Swap (ref x, ref y );
Return (new CaseInsensitiveComparer (). Compare (x, y );
}
// Exchange operations
Private void Swap (ref object x, ref object y)
{
Object temp = null;
Temp = x;
X = y;
Y = temp;
}
}
/// <Summary>
/// Information class used for object comparison
/// </Summary>
Public struct ReverserInfo
{
/// <Summary>
/// The comparison direction is as follows:
/// ASC: ascending
/// DESC: Descending Order
/// </Summary>
Public enum Direction
{
ASC = 0,
DESC,
};
Public enum Target
{
CUSTOMER = 0,
FORM,
FIELD,
SERVER,
};
Public string name;
Public Direction direction;
Public Target target;
}
/// <Summary>
/// Inherit from the IComparer <T> interface to compare objects of the same custom type
/// </Summary>
/// <Typeparam name = "T"> T is a generic type </typeparam>
Public class Reverser <T>: IComparer <T>
{
Private Type type = null;
Private ReverserInfo info;
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "type"> comparison class type </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (Type type, string name, ReverserInfo. Direction direction)
{
This. type = type;
This.info. name = name;
If (direction! = ReverserInfo. Direction. ASC)
This.info. direction = direction;
}
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "className"> name of the class to be compared </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (string className, string name, ReverserInfo. Direction direction)
{
Try
{
This. type = Type. GetType (className, true );
This.info. name = name;
This.info. direction = direction;
}
Catch (Exception e)
{
Throw new Exception (e. Message );
}
}
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "t"> compare instances </param>
/// <Param name = "name"> compare the property name of an object </param>
/// <Param name = "direction"> comparison direction (ascending/descending) </param>
Public Reverser (T t, string name, ReverserInfo. Direction direction)
{
This. type = t. GetType ();
This.info. name = name;
This.info. direction = direction;
}
// Required! Compare the implementation of IComparer <T>.
Int IComparer <T>. Compare (T t1, T t2)
{
Object x = this. type. InvokeMember (this.info. name, BindingFlags. Public | BindingFlags. Instance | BindingFlags. GetProperty, null, t1, null );
Object y = this. type. InvokeMember (this.info. name, BindingFlags. Public | BindingFlags. Instance | BindingFlags. GetProperty, null, t2, null );
If (this.info. direction! = ReverserInfo. Direction. ASC)
Swap (ref x, ref y );
Return (new CaseInsensitiveComparer (). Compare (x, y );
}
// Exchange operations
Private void Swap (ref object x, ref object y)
{
Object temp = null;
Temp = x;
X = y;
Y = temp;
}
}
/// <Summary>
/// Information class used for object comparison
/// </Summary>
Public struct ReverserInfo
{
/// <Summary>
/// The comparison direction is as follows:
/// ASC: ascending
/// DESC: Descending Order
/// </Summary>
Public enum Direction
{
ASC = 0,
DESC,
};
Public enum Target
{
CUSTOMER = 0,
FORM,
FIELD,
SERVER,
};
Public string name;
Public Direction direction;
Public Target target;
}
After writing it, you only need to know how to call it:
[Csharp]
Reverser <Model> reverser = new Reverser <Model> (typeof (Model), "btnIndex", ReverserInfo. Direction. ASC );
Reverser <Model> reverser = new Reverser <Model> (typeof (Model), "btnIndex", ReverserInfo. direction. ASC); we get a defined sorting rule reverser through this call method. If our generic instance is named list, we will call it as follows:
[Csharp]
List. Sort (reverser );
List. Sort (reverser );
Now, specific sorting rules are processed.
Background:
Although there are not many such requirements, it is very practical to display them in order according to a certain attribute in the custom-constructed generic type.
At the same time, any generic set composed of custom classes can achieve custom sorting and can be made into a general class. There is no need for each custom class to implement the sorting interface.