前言
在編程過程中,我們在處理復雜的數據結構或對項目列表進行排序,需要用到對象的比較。在 C# 中,IComparer 與 IComparer<T> 提供了一種靈活而強大的方法來定義自定義比較邏輯,以便可以對它們進行排序。它們功能上相似,只在使用泛型方面有所不同。本文我們探索如何有效地實現和使用它們。
IComparer
1、概述
IComparer 是用于定義比較兩個對象方法的接口,在默認排序行為不能滿足我們的需求或需要根據自定義條件對對象進行排序。它是在 Collections 命名空間中的,只由單個方法組成。
public interface IComparer
{
/// <summary>
/// 比較兩個對象 x 與 y
/// </summary>
/// <param name="x">對象 x </param>
/// <param name="y">對象 y </param>
/// <returns>
/// 如果 x 小于 y,則為負整數
/// 如果 x 大于 y,則為正整數
/// 如果 x 等于 y,則為零
/// </returns>
int Compare(object x, object y);
}
2、實現
實現 IComparer,我們需要創建一個實現IComparer接口Compare方法的類。根據需要進行排序的自定義比較邏輯,實現該方法。下面通過示例(實現客戶集合按地區、再按名稱排序)探索如何實現和使用IComparer。
我們簡化類的定義,只包含編碼、名稱、地區與構造方法。namespace Fountain.WinConsole.ComparerDemo
{
public class Customer
{
public string Code { get; set; }
public string Name { get; set; }
public string City { get; set; }
/// <summary>
///
/// </summary>
/// <param name="code">編碼</param>
/// <param name="name">名稱</param>
/// <param name="city">城市</param>
/// <returns></returns>
public Customer(string code, string name, string city)
{
this.Code = code;
this.Name = name;
this.City = city;
}
}
}
實現接口的 Comparer方法, 定義按客戶的地區、名稱的比較邏輯。using System;
using System.Collections;
namespace Fountain.WinConsole.ComparerDemo
{
public class CustomerComparer : IComparer
{
/// <summary>
/// 比較兩個對象 x 與 y
/// </summary>
/// <param name="x">對象 x </param>
/// <param name="y">對象 y </param>
/// <returns></returns>
public int Compare(object x, object y)
{
if (x == null || y == null)
{
throw new ArgumentException("參數未引用實例");
}
// 對象 x 轉為 Customer
Customer customerx = x as Customer;
// 對象 x 轉為 Customer
Customer customery = y as Customer;
if (customerx == null || customery == null)
{
throw new ArgumentException("二個參數不是 Customer 類型");
}
// 先比較城市
int cityComparison = string.Compare(customerx.City, customery.City, StringComparison.OrdinalIgnoreCase);
// 如果城市相等,則再比較名稱
if (cityComparison == 0)
{
// 再比較名稱
return string.Compare(customerx.Name, customery.Name, StringComparison.OrdinalIgnoreCase);
}
return cityComparison;
}
}
}
使用 CustomerComparer 對客戶列表進行排序,定義了客戶數組列表。
using System;
namespace Fountain.WinConsole.ComparerDemo
{
internal class Program
{
public static void Main()
{
// 創建客戶數組列表
var customers = new Customer[]
{
new Customer("Huawei", "華為","深圳"),
new Customer("Dajiang", "大疆", "深圳"),
new Customer("Guangqi", "廣汽", "廣州"),
new Customer("NanfangDiawang", "中國南方電網", "廣州"),
new Customer("Meidi", "美的", "佛山")
};
// 使用 CustomerComparer 對客戶列表進行排序
Array.Sort(customers, new CustomerComparer());
Console.WriteLine("客戶排序按 城市 和 名稱排序");
foreach (var customer in customers)
{
// 出排序結果
Console.WriteLine($"{customer.City} {customer.Name}");
}
Console.ReadKey();
}
}
}
IComparer<T>
1、概述
IComparer<T> 是用于定義比較兩個對象方法的泛型接口,這個接口是在 System.Collections.Generic 命名空間中的,只由單個方法組成。
public interface IComparer<T>
{
/// <summary>
/// 比較兩個對象 x 與 y
/// </summary>
/// <param name="x">對象 x </param>
/// <param name="y">對象 y </param>
/// <returns>
/// 如果 x 小于 y,則為負整數
/// 如果 x 大于 y,則為正整數
/// 如果 x 等于 y,則為零
/// </returns>
int Compare(T x, T y);
}
2、實現
實現 IComparer<T>,我們需要創建一個實現IComparer<T>接口Compare方法的類。根據需要進行排序的自定義比較邏輯,實現該方法。下面通過示例(實現客戶集合按地區、再按名稱排序)探索如何實現和使用IComparer<T>。
我們簡化類的定義,只包含編碼、名稱、地區與構造方法。此類已在上面示例給出。
實現接口的 Comparer方法, 定義按客戶的地區、名稱的比較邏輯。
using System;
using System.Collections.Generic;
namespace Fountain.WinConsole.ComparerDemo
{
public class CustomerComparer : IComparer<Customer>
{
/// <summary>
/// 比較兩個對象 x 與 y
/// </summary>
/// <param name="customerx">對象 x </param>
/// <param name="customery">對象 y </param>
/// <returns></returns>
public int Compare(Customer customerx, Customer customery)
{
if (customerx == null || customery == null)
{
throw new ArgumentException("二個參數不是 Customer 類型");
}
// 先比較城市
int cityComparison = string.Compare(customerx.City, customery.City, StringComparison.OrdinalIgnoreCase);
// 如果城市相等,則再比較名稱
if (cityComparison == 0)
{
// 再比較名稱
return string.Compare(customerx.Name, customery.Name, StringComparison.OrdinalIgnoreCase);
}
return cityComparison;
}
}
}
使用 CustomerComparer 對客戶列表進行排序,定義客戶List列表。
using System;
using System.Collections.Generic;
namespace Fountain.WinConsole.ComparerDemo
{
internal class Program
{
public static void Main()
{
// 創建客戶數組列表
var customers = new Customer[]
{
new Customer("Huawei", "華為","深圳"),
new Customer("Dajiang", "大疆", "深圳"),
new Customer("Guangqi", "廣汽", "廣州"),
new Customer("NanfangDiawang", "中國南方電網", "廣州"),
new Customer("Meidi", "美的", "佛山")
};
// 使用 CustomerComparer 對客戶列表進行排序
Array.Sort(customers, new CustomerComparer());
Console.WriteLine("客戶排序按 城市 和 名稱排序");
foreach (var customer in customers)
{
// 出排序結果
Console.WriteLine($"{customer.City} {customer.Name}");
}
// 創建客戶數組列表
var customerList = new List<Customer>
{
new Customer("Huawei", "華為","深圳"),
new Customer("Dajiang", "大疆", "深圳"),
new Customer("Guangqi", "廣汽", "廣州"),
new Customer("NanfangDiawang", "中國南方電網", "廣州"),
new Customer("Meidi", "美的", "佛山")
};
Console.WriteLine();
// 使用 CustomerComparer 對客戶列表進行排序
customerList.Sort(new CustomerComparer());
Console.WriteLine("客戶排序按 城市 和 名稱排序");
foreach (var customer in customerList)
{
// 出排序結果
Console.WriteLine($"{customer.City} {customer.Name}");
}
Console.ReadKey();
}
}
}
優點
小結
以上是 IComparer 和 IComparer<T> 在 C# 中,通過遵循分步實施示例,探索如何有效地實現和使用它們。通過分步實現的示例,我們可以輕松地將它們集成到項目中,并控制對象的排序和比較方式。
該文章在 2024/11/15 11:55:38 編輯過