118. IComparer{T} interface

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

למשל, אנחנו עשויים לרצות להשוות מחרוזות דווקא לפי האורך שלהן, ולא לפי המקום שלהם במילון.

באופן אנלוגי לIEqualityComparer (טיפ מספר 111) המאפשר לנו להשוות איברים בצורה מלאכותית, ולאו דווקא באמצעות פונקצית הEquals של האובייקט, קיים פתרון מקביל גם עבור IComparable.

הפתרון הוא ממשק ששמו IComparer המאפשר לנו להגדיר כיצד להשוות איברים מבחוץ. יש לו פונקציה אחת:

1
public int Compare(T x, T y)

אותה אנחנו צריכים לממש, ולהחליט כיצד להשוות איברים.

קיימת גם גרסה לא גנרית של ממשק זה המשווה objectים. במידה ואנחנו מעוניינים לממש את שני הממשקים, נוכל לרשת מהטיפוס Comparer<T>. כך נצטרך רק לממש את הפונקציה הגנרית, ונקבל מימוש Out of the boxשל המימוש של objectים.

למשל, בדוגמה של השוואת מחרוזות לפי האורך שלהן:

1
2
3
4
5
6
7
public class StringLengthComparer : Comparer<string>
{
public override int Compare(string x, string y)
{
return (x.Length - y.Length);
}
}

השוואה מתבצעת באמצעות:

1
2
3
4
5
6
StringLengthComparer comparer = new StringLengthComparer();
if (comparer.Compare("Hellllo", "world") > 0)
{
// True
}

בנוסף, אם אנחנו מעוניינים מאיזושהי סיבה לקבל Comparer שמשתמש בפונקציה CompareTo, במידה והטיפוס שלנו מממש IComparable<T>, נוכל להשתמש בComparer הסטטי הבא:

1
Comparer<T>.Default

כמובן, לרוב הפונקציות שמשתמשות בממשק IComparable<T> בשביל להשוות איברים, קיים overload שמאפשר לציין באמצעות איזה Comparer להשוות.

אולי עוד נראה לזה דוגמאות.

המשך יום בר השוואה טוב

שתף