Last active
December 3, 2025 14:06
-
-
Save zhaopan/7c2d91d2c6d1d11eb828c3ac9138daec to your computer and use it in GitHub Desktop.
ListComparer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| /// <summary> | |
| /// 物料代码实体。 | |
| /// </summary> | |
| public class EntMaterielCodes | |
| { | |
| public string? RFIDCode { get; set; } | |
| public string? UniqueCode { get; set; } | |
| public override string ToString() | |
| { | |
| return $"[RFID: {RFIDCode ?? "N/A"}, UniqueCode: {UniqueCode ?? "N/A"}]"; | |
| } | |
| } | |
| /// <summary> | |
| /// 用于比较 EntMaterielCodes 对象的相等性和哈希码。 | |
| /// </summary> | |
| public class MaterielCodesComparer : IEqualityComparer<EntMaterielCodes> | |
| { | |
| /// <summary> | |
| /// 检查两个 EntMaterielCodes 实例是否基于它们的 RFIDCode 和 UniqueCode 字段相等。 | |
| /// </summary> | |
| public bool Equals(EntMaterielCodes? x, EntMaterielCodes? y) | |
| { | |
| if (Object.ReferenceEquals(x, y)) return true; | |
| if (x is null || y is null) return false; | |
| // 使用 Ordinal 比较字符串,确保比较的确定性和性能。 | |
| return StringComparer.Ordinal.Equals(x.RFIDCode, y.RFIDCode) && | |
| StringComparer.Ordinal.Equals(x.UniqueCode, y.UniqueCode); | |
| } | |
| /// <summary> | |
| /// 基于 RFIDCode 和 UniqueCode 计算对象的哈希码。 | |
| /// </summary> | |
| public int GetHashCode(EntMaterielCodes obj) | |
| { | |
| if (obj is null) return 0; | |
| // 使用 ValueTuple 的 GetHashCode 方法结合两个属性生成哈希码。 | |
| return (obj.RFIDCode, obj.UniqueCode).GetHashCode(); | |
| } | |
| } | |
| // 假设这些是您的源数据结构 | |
| public class SourceCodeEntity | |
| { | |
| public string? RFIDCode { get; set; } | |
| public string? UniqueCode { get; set; } | |
| } | |
| public class NewCodeEntity | |
| { | |
| public string? RFID { get; set; } | |
| public string? UniqueCode { get; set; } | |
| } | |
| public class Sample | |
| { | |
| private readonly IEnumerable<SourceCodeEntity> codes = new List<SourceCodeEntity> | |
| { | |
| new SourceCodeEntity { RFIDCode = "A1", UniqueCode = "U1" }, | |
| new SourceCodeEntity { RFIDCode = "B2", UniqueCode = "U2" }, | |
| new SourceCodeEntity { RFIDCode = "C3", UniqueCode = "U3" } | |
| }; | |
| private readonly IEnumerable<NewCodeEntity> newCodes = new List<NewCodeEntity> | |
| { | |
| new NewCodeEntity { RFID = "C3", UniqueCode = "U3" }, | |
| new NewCodeEntity { RFID = "D4", UniqueCode = "U4" }, | |
| new NewCodeEntity { RFID = "E5", UniqueCode = "U5" } | |
| }; | |
| private void Run() | |
| { | |
| // 以前的码(旧库存)投影 | |
| var oldCodesProjection = codes | |
| .Select(x => new EntMaterielCodes { RFIDCode = x.RFIDCode, UniqueCode = x.UniqueCode }); | |
| // 当前传入的码(新盘点/传入)投影 | |
| var newCodesProjection = newCodes | |
| .Select(x => new EntMaterielCodes { RFIDCode = x.RFID, UniqueCode = x.UniqueCode }); | |
| var comparer = new MaterielCodesComparer(); | |
| // 将旧集合转换为 HashSet 以提高 Except 和 Intersect 的查找性能 | |
| var oldSet = oldCodesProjection.ToHashSet(comparer); | |
| // 亏 (Deficit): 在旧集合中,但不在新集合中 | |
| var deficitList = oldSet | |
| .Except(newCodesProjection, comparer) | |
| .ToList(); | |
| // 盈 (Surplus): 在新集合中,但不在旧集合中 | |
| var surplusList = newCodesProjection | |
| .Except(oldSet, comparer) | |
| .ToList(); | |
| // 正常 (Normal): 新旧集合的交集 | |
| var intersectList = newCodesProjection | |
| .Intersect(oldSet, comparer) | |
| .ToList(); | |
| Console.WriteLine($"--- 亏损项 ---"); | |
| deficitList.ForEach(c => Console.WriteLine(c)); | |
| Console.WriteLine($"\n--- 盈余项 ---"); | |
| surplusList.ForEach(c => Console.WriteLine(c)); | |
| Console.WriteLine($"\n--- 正常项 ---"); | |
| intersectList.ForEach(c => Console.WriteLine(c)); | |
| } | |
| public static void Main(string[] args) | |
| { | |
| new Sample().Run(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment