Bu arayüzlerden hangisini uygulamam gerektiğini bulmaya çalışıyorum. İkisi de aslında aynı şeyi yapıyor. Ne zaman birini diğerine tercih ederim?
Yanıtlar:
Pekala , iki farklı nesneyi karşılaştırabilen bir tür üzerinde uygulanmış olanla tam olarak aynı şey değildirler , ancak aynı türden diğer örneklerle kendilerini karşılaştırabilen türlerde uygulanır.IComparer<T>
IComparable<T>
IComparable<T>
Başka bir örneğin örnekle nasıl ilişkili olduğunu bilmem gereken zamanlar için kullanma eğilimindeyim this
. karşılaştırmanın dışında IComparer<T>
olduğu için koleksiyonları sıralamak için kullanışlıdır IComparer<T>
.
IComparable
olarak ben karşılaştırılabilir değilim . bu da başka bir şeyle karşılaştırılabileceğim anlamına geliyor. Ve okundu IComparer
olarak ben comparer değilim, ben sadece karşılaştırmak Bazı şeyleri karşılaştırmak hangi araçlar.
Varlığa bağlıdır. Örneğin "Öğrenci" gibi bir sınıfı takip etmek, Ada göre IComparable'a sahip olmak mantıklı olacaktır.
class Student : IComparable
{
public string Name { get; set; }
public int MathScore { get; set; }
public int EnglishScore { get; set; }
public int TotalScore
{
get
{
return this.MathScore + this.EnglishScore;
}
}
public int CompareTo(object obj)
{
return CompareTo(obj as Student);
}
public int CompareTo(Student other)
{
if (other == null)
{
return 1;
}
return this.Name.CompareTo(other.Name);
}
}
Ancak bir öğretmen 'A' öğrencileri MathScore'a göre karşılaştırmak istiyorsa ve öğretmen 'B' öğrencileri EnglishScore'a göre karşılaştırmak istiyorsa. IComparer'ı ayrı olarak uygulamak iyi bir fikir olacaktır. (Daha çok bir strateji modeli gibi)
class CompareByMathScore : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if (x.MathScore > y.MathScore)
return 1;
if (x.MathScore < y.MathScore)
return -1;
else
return 0;
}
}
Her şey türünüzün değiştirilebilir olup olmadığına bağlıdır. Sen olmalıdır yalnızca olmayan değişken türleri üzerinde IComparable uygulamak. IComparable'ı uygularsanız, ==,! =, <Ve> operatörleriyle birlikte Eşittir'i geçersiz kılmanız gerektiğini unutmayın (bkz. Kod Analizi uyarısı CA1036).
Dave G'den bu blog gönderisinden alıntı :
Ancak doğru yanıt, nesneleriniz değiştirilebilirse IComparable yerine IComparer uygulamak ve gerektiğinde IComparer'ın bir örneğini sıralama işlevlerine geçirmektir.
IComparer, yalnızca o noktada sıralama için kullanılan tek kullanımlık bir nesne olduğundan, nesneniz arzu ettiğiniz herhangi bir değiştirilebilir semantiğe sahip olabilir. Dahası, Eşittir, GetHashCode veya == kullanılmasını gerektirmez ve hatta önermez - dilediğiniz şekilde tanımlayabilirsiniz.
Son olarak, farklı alanlarda veya farklı kurallarla sıralama yapmak için türünüz için birden çok IComparer tanımlayabilirsiniz. Bu, tek bir tanıma bağlı kalmaktan çok daha esnektir.
Kısaca: Değer türleri için IComparable'ı ve başvuru türleri için IComparer'ı kullanın.
Bir hikaye üzerinden basit açıklama
Lise basketbolu. Takımlar için bir okul bahçesi seçimi. Takımımdaki en uzun / en iyi / en hızlı insanları almak istiyorum. Ben ne yaparım?
IComparer Arayüzü - İki kişiyi ayrı ayrı karşılaştırın
Compare(Fred, John)
ve kimin daha iyi olduğunu ortaya çıkarır.IComparable ne olacak? - Kendinizi başka biriyle karşılaştırın
Son zamanlarda FB'de bulundunuz mu? Diğer insanların harika şeyler yaptığını görüyorsunuz: dünyayı dolaşmak, icatlar yaratmak, ben pek de havalı olmayan bir şey yaparken - yaptığımız şey IComparable arayüzünü kullanmak.
Karşılaştırma Sınıfı ne olacak?
Comparer sınıfı, IComparer arabirimini uygulayan soyut bir temel sınıftır. Somut bir uygulamaya sahip olmak için bu sınıftan türetmelisiniz. her neyse, Microsoft, IComparer arabirimini uygulamak yerine Comparer sınıfını KULLANMANIZI önerir:
Comparer sınıfı, IComparer.Compare yönteminin açık bir arabirim uygulaması ve nesne için varsayılan karşılaştırıcıyı alan Default özelliği sağladığından, IComparer arabirimini uygulamak yerine Comparer sınıfından türetmenizi öneririz.
Umarım hikayeler hatırlamana yardımcı olur.
Başkalarının da söylediği gibi, aynı şeyi yapmazlar.
Her durumda, bu günlerde IComparer'ı kullanmıyorum. Neden yapayım? Sorumluluğu (iki nesneyi karşılaştırmak için kullanılan harici bir varlık), LINQ yöntemlerinin çoğunun nasıl çalıştığına benzer şekilde, bir lambda ifadesi ile çok daha temiz bir şekilde ele alınabilir. Karşılaştırmak için nesneleri argüman olarak alan ve bir bool döndüren hızlı bir lambda yazın. Ve nesne kendi içsel karşılaştırma işlemini tanımlıyorsa, bunun yerine IComparable'ı uygulayabilir.
IComparable, bir nesnenin diğeriyle karşılaştırılabileceğini söylüyor. IComparer, herhangi iki öğeyi karşılaştırabilen bir nesnedir.
IComparer, Diziyi sıralamak için kullanılan bir arabirimdir, bu arabirim sınıfı, iki nesneyi karşılaştıracak olan Karşılaştır (T x, T y) yöntemini uygulamaya zorlar. Bu arabirimi uygulayan sınıfın örneği, Dizinin sıralanmasında kullanılır.
IComparable, aynı türdeki iki nesneyi karşılaştırması gereken türde uygulanan bir arabirimdir, Bu karşılaştırılabilir arabirim, sınıfı aşağıdaki yöntemi CompareTo (T obj) uygulamaya zorlayacaktır.
IEqualityComparer, nesneyi Eşit olsun ya da olmasın bulmak için kullanılan bir arayüzdür, Şimdi bunu bir Nesnenin Farkını bir koleksiyonda bulmamız gereken bir örnekte göreceğiz. Bu arayüz bir Eşit yöntem uygulayacak (T obj1, T obj2)
Şimdi bir Örnek alıyoruz, bir Çalışan sınıfımız var, bu sınıfa dayalı olarak bir Koleksiyon oluşturmamız gerekiyor. Şimdi aşağıdaki gereksinimlerimiz var.
Diziyi Array sınıfı 2 kullanarak sıralayın. Linq kullanarak bir koleksiyona ihtiyacınız var: Yinelemeyi kaldırın, Yukarıdan aşağıya sıralayın, Bir çalışan kimliğini kaldırın
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
public class EmployeeIdSorter: IComparer {public int Compare (Employee x, Employee y) {if (x.Id <y.Id) return 1; aksi takdirde (x.Id> y.Id) -1 döndürür; aksi takdirde 0 döndürür; }}
public class EmployeeSalarySorter : IComparer<Employee>
{
public int Compare(Employee x, Employee y)
{
if (x.Salary < y.Salary)
return 1;
else if (x.Salary > y.Salary)
return -1;
else
return 0;
}
}
Daha fazla bilgi için aşağıdaki hakem http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html