Varsayılan olarak, Distinct linq operatörü kullanıldığında Equals yöntemini kullanır, ancak IEqualityComparer<T>iki nesnenin özel bir mantık uygulaması GetHashCodeve Equalsyöntemiyle ne zaman eşit olduğunu belirtmek için kendi nesnenizi kullanabilirsiniz . Bunu hatırla:
GetHashCodeağır cpu karşılaştırması kullanılmamalıdır (örneğin, yalnızca bazı açık temel kontrolleri kullanın) ve iki nesnenin kesinlikle farklı (farklı karma kod döndürülürse) veya potansiyel olarak aynı (aynı karma kod) olup olmadığını belirtmek için ilk olarak kullanılmalıdır. Bu son durumda, iki nesne aynı hashcode'a sahip olduğunda, çerçeve, verilen nesnelerin eşitliği hakkında nihai bir karar olarak Equals yöntemini kullanarak kontrol etmeye başlayacaktır.
Siz MyTypeve bir MyTypeEqualityComparersınıf takip ettikten sonra , dizinin sırasını korumasını sağlamayın:
var cmp = new MyTypeEqualityComparer();
var lst = new List<MyType>();
var q = lst.Distinct(cmp);
Follow sci kitaplığında, Vector3D setinin belirli bir uzantı yöntemi kullanırken sırayı korumasını sağlamak için bir uzantı yöntemi uyguladım DistinctKeepOrder:
ilgili kod şöyledir:
public class Vector3DWithOrder
{
public int Order { get; private set; }
public Vector3D Vector { get; private set; }
public Vector3DWithOrder(Vector3D v, int order)
{
Vector = v;
Order = order;
}
}
public class Vector3DWithOrderEqualityComparer : IEqualityComparer<Vector3DWithOrder>
{
Vector3DEqualityComparer cmp;
public Vector3DWithOrderEqualityComparer(Vector3DEqualityComparer _cmp)
{
cmp = _cmp;
}
public bool Equals(Vector3DWithOrder x, Vector3DWithOrder y)
{
return cmp.Equals(x.Vector, y.Vector);
}
public int GetHashCode(Vector3DWithOrder obj)
{
return cmp.GetHashCode(obj.Vector);
}
}
Kısacası Vector3DWithOrder, Vector3DWithOrderEqualityComparerorijinal tür karşılaştırıcısını kapsüllerken, türü ve bir sıra tamsayısını kapsülleyin.
ve bu, düzenin korunmasını sağlamak için yöntem yardımcısıdır
public static IEnumerable<Vector3D> DistinctKeepOrder(this IEnumerable<Vector3D> vectors, Vector3DEqualityComparer cmp)
{
var ocmp = new Vector3DWithOrderEqualityComparer(cmp);
return vectors
.Select((w, i) => new Vector3DWithOrder(w, i))
.Distinct(ocmp)
.OrderBy(w => w.Order)
.Select(w => w.Vector);
}
Not : Daha fazla araştırma, daha genel (arayüz kullanımları) ve optimize edilmiş bir yol (nesneyi kapsüllemeden) bulmaya izin verebilir.