using System.Collections.Generic;
using System.Linq;
namespace YourProject.Extensions
{
public static class ListExtensions
{
public static bool SetwiseEquivalentTo<T>(this List<T> list, List<T> other)
where T: IEquatable<T>
{
if (list.Except(other).Any())
return false;
if (other.Except(list).Any())
return false;
return true;
}
}
}
Bazen sadece iki listenin farklı olup olmadığını bilmeniz gerekir , bu farklılıkların ne olduğunu değil. Bu durumda, projenize bu uzantı yöntemini eklemeyi düşünün. Listelenen nesnelerin IEquatable uygulaması gerektiğini unutmayın!
Kullanımı:
public sealed class Car : IEquatable<Car>
{
public Price Price { get; }
public List<Component> Components { get; }
...
public override bool Equals(object obj)
=> obj is Car other && Equals(other);
public bool Equals(Car other)
=> Price == other.Price
&& Components.SetwiseEquivalentTo(other.Components);
public override int GetHashCode()
=> Components.Aggregate(
Price.GetHashCode(),
(code, next) => code ^ next.GetHashCode()); // Bitwise XOR
}
Component
Sınıf ne olursa olsun, burada gösterilen yöntemler Car
neredeyse aynı şekilde uygulanmalıdır.
GetHashCode'u nasıl yazdığımızı not etmek çok önemlidir. Sipariş düzgün uygulamak ise IEquatable
, Equals
ve GetHashCode
gereken bir mantıksal uyumlu şekilde örneğin özelliklerinin üzerinde işlem.
Aynı içeriklere sahip iki liste hala farklı nesnelerdir ve farklı karma kodlar oluşturur. Bu iki listenin eşit olarak ele alınmasını istediğimizden, GetHashCode
her biri için aynı değeri üretmemize izin vermeliyiz . Bunu, hashcode'u listedeki her öğeye devrederek ve hepsini birleştirmek için standart bitsel XOR'u kullanarak başarabiliriz. XOR sıraya göre değişmez, bu nedenle listelerin farklı sıralanması önemli değildir. Sadece eşdeğer üyelerden başka bir şey içermemeleri önemlidir.
Not: garip ad, yöntemin listedeki öğelerin sırasını dikkate almadığı anlamına gelir. Listedeki öğelerin sırasını önemsiyorsanız, bu yöntem sizin için değildir!