Enumerable khác với list như thế nào
Một collection (bộ, tập hợp) là một nhóm các đối tượng có sự liên quan đến nhau. Số đối tượng trong collect có thể thay đổi tăng giảm. Có nhiều loại collection, chúng được tập hợp vào namespace
using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }9. Thường thì một lớp collection có các phương thức để thêm, bớt, lấy tổng phần tử. Show .NET cung cấp một số các lớp collection kiểu Generic như: var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 0, var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 1, var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 2 ... những lớp generic này ở namespace System.Collections.Generic Tìm hiểu phần này bạn cần nắm vững về Generic trong C# trước Ngoài ra namespace System.Collections cũng có các lớp collection mà không sử dụng generic như: var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 3, var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 2, var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 5 ... Các giao diện - interface về collect mà bạn có thể sử dụng InterfaceMô tảIEnumerableTriển khai nó nếu muốn duyệt phần tử bằngvar numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 6, nó định nghĩa phương thức GetEnumerator trả về một enumerator.ICollectionGiao diện này được triển khai bở các generic collection. Với nó lấy tổng phần tử bằng thuộc tính var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 7, copy các phần tử vào mảng bằng var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 8, thêm bớt phần tử với var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 9, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 0, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 1IListGiao diện này kế thừa ICollectionlà một danh sách các phần tử truy cập được theo vị trí của nó. Nó có indexer, phương thức để chèn phần tử xóa phần tử var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 2 var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 3.ISetGiao diện triển khai bởi các tập hợpIDictionaryGiao diện để triển khai loại dữ liệu lưu trữ theo cặp key, value.ILookupGiao diện để triển khai loại dữ liệu lưu trữ theo cặp key, value. Nhưng cho phép một key có nhiều giá trịIComparerGiao diện để triển khai cho phép so sánh để sắp xếp CollectionIEqualityComparerGiao diện để triển khai cho phép so sánh bằng Lớp ListLớp collection var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 0 là lớp triển khai các giao diện IList, ICollection, IEnumerable nó quản lý danh sách các đối tượng cùng kiểu. Bạn có thể thêm, bớt, truy cập, sắp xếp các phần tử trong danh sách bằng các phương thức nó cung cấp như var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 9, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 6, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 2, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 3, var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; 0 ... các phương thức này chi tiết theo ví dụ dưới Khởi tạo một danh sách List, mà các phần tử có kiểu element_type: var list = new List(); Ví dụ, xây dựng danh sách các sản phẩm, sản phẩm có kiểu var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List0 tự định nghĩa như sau - lớp sản phẩm hỗ trợ so sánh với sản phẩm khác nên triển khai IComparable, cho phép hiện lấy một chuỗi thông tin bằng ToString với định dạng nào đó nên triển khai giao diện IFormattable Mã nguồn xây dựng lớp var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List0 trong file Product.cs như sau: using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } } Khởi tạo ListĐể khởi tạo một danh sách rỗng, dùng toán tử var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List2 var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product Khởi tạo danh sách có sẵn một số phần tử, thì các phần tử liệt kê sau var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List3 var numbers = new List() {1,2,3,4}; // khởi tạo 4 phần tử var products = new List() // khởi tạo 1 phần tử { new Product(1, "Iphone 6", 100, "Trung Quốc") }; Thêm, xóa, chèn và đọc phần tử trong List1 THÊM PHẦN TỬ vào cuối danh sách sử dụng phương thức Add var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List Nếu muốn thêm nhiều phần tử một lúc (mảng các phần tử), dùng AddRange var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách 2 CHÈN PHẦN TỬ vào danh sách, phần tử sẽ ở vị trí chỉ ra dùng phương thức var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List4 hoặc chèn cả một mảng var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List5. Trong đó var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List6 là vị trí chèn phần tử (0 là đầu tiên). products.Insert(3, new Product(6, "Macbook Pro", 1000, "Mỹ")); // chèn phần tử vào vị trí index 3, (thứ 4) 3 ĐỌC PHẦN TỬ trong List bạn dùng indexer với chỉ số (chỉ số bắt đầu từ 0). Ví dụ lấy phần tử ở Index = 1; var pro = products[2]; // đọc phần tử có index = 2 Console.WriteLine(pro.ToString()); Để duyệt qua các phần tử bạn có thể dùng lệnh var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List7 hoặc var numbers = new List(); // danh sách số nguyên var products = new List(); // danh sách Product 6 // Duyệt qua tất cả các phần tử bằng for // products.Count = lấy tổng phần tử trong List for (int i = 1; i < products.Count; i++) { var pi = products[i - 1]; Console.WriteLine(pi.ToString()); } // Duyệt qua các phần tử bằng foreach foreach (var pi in products) { Console.WriteLine(pi.ToString()); } 4 XÓA PHẦN TỬ trong List - để xóa phần tử ở vị trí index dùng var p = new Product(2, "IPhone 7", 200, "Trung Quốc"); products.Add(p); // Thêm p vào cuối List products.Add(new Product(3, "IPhone 8", 400, "Trung Quốc")); // thêm đối tượng mới vào cuối List9, để xóa cả một đoạn count phần tử, từ vị trí index dùng var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách0, để xóa toàn bộ (làm rỗng) gọi var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách1 hoặc var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách2 products.RemoveAt(0); // xóa phần tử đầu tien products.RemoveRange(products.Count - 2, 2); // xóa 2 phần tử cuối Khi bạn có tham chiếu đến đối tượng đang có trong List, cũng có thể loại nó bằng var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách3 using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }0 Tìm kiếm thông tin trong ListMột số phương thức cho phép tìm kiếm, tra cứu vị trị trí các phần tử trong List Phương thứcMô tảvar arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách4Tìm index của đối tượng trong List var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách5Tìm index của phần tử cuối cùng có giá trị bằng obj trong List var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách6Tìm kiếm trả về Index var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách7Tìm kiếm trả về Index cuối var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách8Tìm kiếm trả về phần tử var arrayProducts = new Product[] // Mảng 2 phần tử { new Product(4, "Glaxy 7", 500, "Việt Nam"), new Product(5, "Glaxy 8", 700, "Việt Nam"), }; products.AddRange(arrayProducts); // Nối các phần tử của mảng vào danh sách9Tìm kiếm trả về danh sách phần tử products.Insert(3, new Product(6, "Macbook Pro", 1000, "Mỹ")); // chèn phần tử vào vị trí index 3, (thứ 4)0Tìm kiếm trả về phần tử cuối tìm thấy Trong các phương thức trên, có các phương thức ví dụ Find, chứa tham số là delegate products.Insert(3, new Product(6, "Macbook Pro", 1000, "Mỹ")); // chèn phần tử vào vị trí index 3, (thứ 4)1, nó là hàm callback, trả về true là phần tử phù hợp trả về (xem về sử dụng delegate trong C#) Ví dụ sau đây là một Delegate phù hợp gán cho tham số Predicate using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }1 Đoạn mã này có thể làm tham số cho Find, FindAll ... using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }2 Các delegate cũng có thể viết gọn lại using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }3 Nếu muốn tùy biến cao hơn Delegate, để tìm kiếm theo tham số tùy chọn, bạn có thể để Delegate trên vào lớp chức năng, ví dụ xây dựng lớp SearchNameProduct using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }4 Thực hiện tìm kiếm, ví dụ using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }5 Sắp xếp các phần tử trong ListĐể sắp xếp các phần tử trong danh sách, nếu phần tử đó có triển khai giao diện IComparable thì chỉ việc gọi products.Insert(3, new Product(6, "Macbook Pro", 1000, "Mỹ")); // chèn phần tử vào vị trí index 3, (thứ 4)2 để có danh sách theo thứ tự. Ví dụ trên, lớp Product có triển khai IComparable, với phương thức CompareTo, thì sản phẩm nào có giá cao hơn xếp trước, có giá thấp hơn xếp sau. using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }6 using System; namespace CS017_Generic { public class Product : IComparable, IFormattable { public int ID {set; get;} public string Name {set; get;} // tên public double Price {set; get;} // giá public string Origin {set; get;} // xuất xứ public Product(int id, string name, double price, string origin) { ID = id; Name = name; Price = price; Origin = origin; } //Triển khai IComparable, cho biết vị trí sắp xếp so với đối tượng khác // trả về 0 - cùng vị trí; trả về > 0 đứng sau other; < 0 đứng trước trong danh sách public int CompareTo(Product other) { // sắp xếp về giá double delta = this.Price - other.Price; if (delta > 0) // giá lớn hơn xếp trước return -1; else if (delta < 0) // xếp sau, giá nhỏ hơn return 1; return 0; } // Triển khai IFormattable, lấy chuỗi thông tin của đối tượng theo định dạng // format hỗ trợ "O" và "N" public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "O"; switch (format.ToUpper()) { case "O": // Xuất xứ trước return $"Xuất xứ: {Origin} - Tên: {Name} - Giá: {Price} - ID: {ID}"; case "N": // Tên xứ trước return $"Tên: {Name} - Xuất xứ: {Origin} - Giá: {Price} - ID: {ID}"; default: // Quăng lỗi nếu format sai throw new FormatException("Không hỗ trợ format này"); } } // Nạp chồng ToString override public string ToString() => $"{Name} - {Price}"; // Quá tải thêm ToString - lấy chỗi thông tin sản phẩm theo định dạng public string ToString(string format) => this.ToString(format, null); } }7 Bạn cũng có thể tùy biến cách thức sắp xếp bằng cách cung cấp hàm callback dạng deleage hai tham số kiểu cùng với kiểu phần tử cho Search, thay vì sắp xếp mặc định như trên. |