Skip to content

Instantly share code, notes, and snippets.

@zhaopan
Last active December 3, 2025 14:06
Show Gist options
  • Select an option

  • Save zhaopan/7c2d91d2c6d1d11eb828c3ac9138daec to your computer and use it in GitHub Desktop.

Select an option

Save zhaopan/7c2d91d2c6d1d11eb828c3ac9138daec to your computer and use it in GitHub Desktop.
ListComparer
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