266. StructuralComparisons StructuralEqualityComparer

אז ראינו בפעם שעברה שאפשר להשוואות מערכים או Tupleים באמצעות הממשק IStructuralEquatable.

היינו רוצים להשוואות לפעמים מסיבות כאלה ואחרות באמצעותEqualityComparer מתאים. (כי הFramework תומך בזה בהרבה מקומות)

למרבה המזל, קיים כזה בFramework:

1
StructuralComparisons.StructuralEqualityComparer

הוא EqualityComparer סטטי המשווה שניIStructuralEquatable.

למשל:

1
2
3
4
5
6
7
int[] theNumbers = new int[] {4, 8, 15, 16, 23, 42};
int[] evil = new [] {4, 8, 15, 16, 23, 42};
if (StructuralComparisons.StructuralEqualityComparer.Equals(theNumbers, evil))
{
// True
}

יש פה משהו קצת מוזר: איפה הEqualityComparer שדיברנו עליו פעם קודמת?

למרבה הצער, אנחנו לא יכולים לציין עם איזה EqualityComparer תתבצע השוואת האיברים, ולכן היא מתבצעת עם… StructuralComparisons.StructuralEqualityComparer עצמו:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[Serializable]
internal class StructuralEqualityComparer : IEqualityComparer
{
public bool Equals(object x,object y)
{
if (x != null)
{
IStructuralEquatable structuralEquatable = x as IStructuralEquatable;
if (structuralEquatable != null)
{
return structuralEquatable.Equals(y, (IEqualityComparer) this);
}
if (y != null)
{
return x.Equals(y);
}
else
{
return false;
}
}
else if (y != null)
{
return false;
}
else
{
return true;
}
}
public int GetHashCode(objectobj)
{
if (obj == null)
{
return 0;
}
IStructuralEquatable structuralEquatable = obj as IStructuralEquatable;
if (structuralEquatable !=null)
{
return structuralEquatable.GetHashCode((IEqualityComparer)this);
}
else
{
return obj.GetHashCode();
}
}
}

זה קצת מוזר, אבל זה יכול לעזור לנו במקרים בהם אנחנו רוצים להשוות מבנים מורכבים איבר-איבר עם פונקציית הEquals הסטנדרטית.

מה שכן, אפשר ללמוד מהמחלקה הזאת איך לממש EqualityComparer של IStructuralEquatable, שכן מקבל EqualityComparer מבחוץ…. (למרות שזה לא מסובך!).

המשך יום מורכב טוב!

שתף