Collections are an important concept in OOP, and full support for collections in C# is one of the best of the language.
Why use generic sets? Before C# 2.0, collections could be implemented in two main ways: a. Use ArrayList Putting objects directly into the ArrayList is intuitive, but since the items in the collection are of type Object, you have to do tedious type conversion every time you use it. b. Use custom collection classes A common practice is to inherit a custom class from the CollectionBase abstract class and implement a strong type collection by encapsulating the IList object. This method requires writing a corresponding custom class for each collection type, which is a lot of work. The emergence of generic collections solves the above problems well, and only one line of code can be used to create a set of a specified type. What is generic? Generics are new elements in C# 2.0 (called templates in C++) that are mainly used to solve a series of similar problems. This mechanism allows the class name to be passed as an argument to the generic type and the corresponding object is generated. It may be better to think of generics (including classes, interfaces, methods, delegates, etc.) as templates, where the variant part is replaced by the class name passed as an argument, resulting in a new type definition. Generic is a relatively large topic, and I will not analyze it in detail here, and those who are interested can consult the relevant information. How do I create a generic collection? The List generic class under the System.Collections.Generic namespace <T>is used to create collections, and the syntax is as follows: [mw_shl_code=csharp,true] List<T> ListOfT = new List<T>(); [/mw_shl_code] The "T" is the type to be used, which can be simple types, such as string, int, or user-defined types. Let's look at a specific example.
The Person class is defined as follows: [mw_shl_code=csharp,true]class Person
{ private string _name; Name private int _age; Age
Create a Person object public Person(string Name, int Age) { this._name= Name; this._age = Age; }
Name public string Name { get { return _name; } }
Age public int Age { get { return _age; } }
}
//创建Person对象 Person p1 = new Person("Zhang San", 30); Person p2 = new Person("Li Si", 20); Person p3 = new Person("Wang Wu", 50);
//创建类型为Person的对象集合 List<Person> persons = new List<Person>();
//将Person对象放入集合 persons. Add(p1); persons. Add(p2); persons. Add(p3);
//输出第2个人的姓名 Console.Write(persons[1]. Name); [/mw_shl_code] As you can see, generic collections greatly simplify the implementation code of collections, through which you can easily create collections of specified types. Not only that, but generic collections also provide more powerful functions, let's take a look at the sorting and searching in them. Sorting of generic collections Sorting is based on comparison, and to sort, you must first compare. For example, if there are two numbers 1 and 2, to sort them, we must first compare these two numbers and sort them according to the comparison results. If you want to compare objects, the situation is a little more complicated, for example, if you compare Person objects, you can compare by name or age, which requires determining the comparison rules. An object can have multiple comparison rules, but only one default rule, which is placed in the class that defines the object. The default comparison rules are defined in the CompareTo method, which belongs to the IComparable <T>generic interface. See the code below: [mw_shl_code=csharp,true]class Person :IComparable<Person>
{ Compare by age public int CompareTo(Person p) { return this. Age - p.Age; } }[/mw_shl_code] The parameters of the CompareTo method are another object of the same type to be compared with, the return value is int type, if the return value is greater than 0, it means that the first object is greater than the second object, if the return value is less than 0, it means that the first object is less than the second object, and if it returns 0, the two objects are equal. After defining the default comparison rules, you can sort the collection using the Sort method without parameters, as follows: [mw_shl_code=csharp,true]// Sort the collection according to the default rules persons. Sort();
//输出所有人姓名 foreach (Person p in persons)
{ Console.WriteLine(p.Name); The output order is "Li Si", "Zhang San", and "Wang Wu" }[/mw_shl_code] In practice, it is often necessary to sort the collection according to a variety of different rules, which requires the definition of other comparison rules, which can be defined in the Compare method, which belongs to the IComparer <T>generic interface, please see the following code: [mw_shl_code=csharp,true]class NameComparer : IComparer<Person>
{ Storage sequencer instances public static NameComparer Default = new NameComparer();
Compare by name public int Compare(Person p1, Person p2) { return System.Collections.Comparer.Default.Compare(p1. Name, p2. Name); } }[/mw_shl_code] The parameters of the Compare method are two objects of the same type to be compared, and the return value is of type int, and the return value processing rules are the same as those of the CompareTo method. Comparer.Default returns a built-in Comparer object for comparing two objects of the same type. Here's how to sort the collection with this newly defined comparator: [mw_shl_code=csharp,true]//Sort the collection by name persons. Sort(NameComparer.Default);
//输出所有人姓名 foreach (Person p in persons)
{ Console.WriteLine(p.Name); The output order is "Li Si", "Wang Wu", and "Zhang San" }[/mw_shl_code] You can also sort the collection by delegating, first of all, define a method for the delegate to call to store the comparison rules, and you can use a static method. See the code below: [mw_shl_code=csharp,true]class PersonComparison
{ Compare by name public static int Name(Person p1, Person p2) { return System.Collections.Comparer.Default.Compare(p1. Name, p2. Name); } }[/mw_shl_code] The parameters of the method are two objects of the same type to be compared, the return value is of type int, and the return value processing rule is the same as that of the CompareTo method.Then sort the collection via the built-in generic delegate System.Comparison<T>: [mw_shl_code=csharp,true] System.Comparison<Person> NameComparison = new System.Comparison<Person>(PersonComparison.Name); persons. Sort(NameComparison);
//输出所有人姓名 foreach (Person p in persons)
{ Console.WriteLine(p.Name); The output order is "Li Si", "Wang Wu", and "Zhang San" }[/mw_shl_code] It can be seen that the latter two methods can sort the collection according to the specified rules, but the author prefers to use the delegation method, and can consider putting various comparison rules in a class and then calling them flexibly. Search for generic collections Search is to find items that meet specific conditions from the collection, and multiple search conditions can be defined and called as needed. First, define the search criteria as follows: [mw_shl_code=csharp,true]class PersonPredicate
{ Find middle-aged people (over 40) public static bool MidAge(Person p) { if (p.Age >= 40) return true; else return false; } }[/mw_shl_code] The above search criteria are placed in a static method with a Boolean return type, and items in the collection that meet certain conditions return true, otherwise false.Then search the collection via the built-in generic delegate System.Predicate<T>: [mw_shl_code=csharp,true] System.Predicate<Person> MidAgePredicate = new System.Predicate<Person>(PersonPredicate.MidAge); List<Person> MidAgePersons = persons. FindAll(MidAgePredicate);
//输出所有的中年人姓名 foreach (Person p in MidAgePersons)
{ Console.WriteLine(p.Name); Output "Wang Wu" }[/mw_shl_code] Extension of generic collections What if you want to get the names of all the people in the set, separated by a comma? Considering that the functionality that a single class can provide is limited, it is natural to think <T>of extending the List class, which is also a class and therefore can be extended by inheritance. See the code below: [mw_shl_code=csharp,true]// Define the Persons collection class class Persons : List<Person>
{ Get the names of everyone in the collection public string GetAllNames() { if (this. Count == 0) return "";
string val = ""; foreach (Person p in this) { val += p.Name + ","; }
return val. Substring(0, val. Length - 1); }
}
//创建并填充Persons集合 Persons PersonCol = new Persons(); PersonCol.Add(p1); PersonCol.Add(p2); PersonCol.Add(p3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); Output "Zhang San, Li Si, Wang Wu"[/mw_shl_code] Summary: This article focuses on the use of generics in C# 2.0 to implement collections, as well as to extend the collection function, and the proper use of generic collections can reduce a lot of duplication of work and greatly improve development efficiency. In fact, sets are just a typical application of generics, and if you want to know more about generics, you can consult other relevant materials. Hope this article was useful to you :-)
|