Programing

IComparable을 사용하는 경우

lottogame 2020. 8. 20. 19:23
반응형

IComparable을 사용하는 경우Vs. IComparer


구현해야하는 이러한 인터페이스를 파악하려고합니다. 둘 다 본질적으로 같은 일을합니다. 언제 다른 하나를 사용합니까?


그럼 그들이하지 과 같은 일 IComparer<T>동안 두 개의 서로 다른 객체를 비교 할 수있는 유형에 구현되는 IComparable<T>같은 유형의 다른 인스턴스와 자신을 비교할 수있는 유형에 구현된다.

나는 IComparable<T>다른 인스턴스가 인스턴스와 어떤 관련이 있는지 알아야 할 때 사용하는 경향이 있습니다 this. 비교 IComparer<T>대상이 아니므로 컬렉션을 정렬하는 데 유용합니다 IComparer<T>.


IComparable<T>클래스에 내재적 비교가있을 때 사용 합니다.

IComparer<T>클래스의 고유 비교 (있는 경우) 이외의 비교 방법을 원할 때 사용 합니다.


엔티티에 따라 다릅니다. 예를 들어 "Student"와 같은 클래스의 경우 이름을 기반으로 IComparable을 사용하는 것이 좋습니다.

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);  
    }
}

그런데 'A'선생님이 MathScore를 기준으로 학생들을 비교하고 싶다면 'B'선생님이 EnglishScore를 기준으로 학생들을 비교하고 싶어합니다. IComparer를 별도로 구현하는 것이 좋습니다. (전략 패턴과 비슷 함)

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;
    }
}

그것은 모두 당신의 유형이 변경 가능한지 여부에 달려 있습니다. 변경 불가능한 유형 에서만 IComparable을 구현 해야 합니다 . IComparable을 구현하는 경우 ==,! =, <및> 연산자와 함께 Equals를 재정의해야합니다 (코드 분석 경고 CA1036 참조).

Quoting Dave G from this blog post:

But the correct answer is to implement IComparer instead of IComparable if your objects are mutable, and pass an instance of the IComparer to sorting functions when necessary.

Since the IComparer is just a disposable object used for sorting at that point in time, your object can have any mutable semantics you desire. Furthermore, it doesn't require or even suggest using Equals, GetHashCode, or == - you're free to define it in any way you please.

Finally, you can define multiple IComparer's for your type for sorting on different fields or with different rules. This is much more flexible than being stuck with one definition.

In short: Use IComparable for value types and IComparer for reference types.


Simple Explanation via a story

High school basketball. It's a school yard pick for the teams. I want to get the tallest/best/fastest folks on my team. What do I do?

IComparer Interface - Compare two people separate people

  • This allows me to compare any two guys lined up.........that's basically it. Fred vs John..........i throw them into a concrete class which implements the interface. Compare(Fred, John) and it spits out who's better.

What about IComparable? - Compare yourself with someone else

Have you been on FB recently? You see other folks doing cool things: travelling the world, creating inventions, while I'm doing something not quite as cool - well what we are doing is making use of the IComparable interface.

  • We are comparing the current instance (yourself) with another object (someone else) which is of the same type (person).

What about the Comparer Class?

The Comparer class is an abstract base class which implements the IComparer interface. You should derive from this class to have a concrete implementation. anyways, Microsoft recommends that you DO use the Comparer class rather than implement the IComparer interface:

We recommend that you derive from the Comparer class instead of implementing the IComparer interface, because the Comparer class provides an explicit interface implementation of the IComparer.Compare method and the Default property that gets the default comparer for the object.

Summary

  • IComparer - line up two things and compare.
  • IComparable - compare yourself with others on FB.

Hope the stories help you remember.


As others have said, they don't do the same thing.

In any case, these days I tend not to use IComparer. Why would I? Its responsibility (an external entity used to compare two objects) can be handled much cleaner with a lambda expression, similar to how most of LINQ's methods work. Write a quick lambda which takes the objects to compare as arguments, and returns a bool. And if the object defines its own intrinsic compare operation, it can implement IComparable instead.


IComparable says an object can be compared with another. IComparer is an object that can compare any two items.


IComparer is a interface which is used to sort the Array, this interface will force the class to implement the Compare(T x,T y) method, which will compare the two objects. The instance of the class which implemented this interface is used in the sorting of the Array.

IComparable is a interface is implemented in the type which needs to compare the two objects of the same type, This comparable interface will force the class to implement the following method CompareTo(T obj)

IEqualityComparer is a interface which is used to find the object whether it is Equal or not, Now we will see this in a sample where we have to find the Distinct of a Object in a collection. This interface will implement a method Equals(T obj1,T obj2)

Now we take a Example we have a Employee class , based on this class we have to create a Collection. Now we have the following requirements.

Sort the Array using Array class 2. Need an collection using Linq : Remove the Duplicate, Order by higher to lower, Remove one employee id

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; else if (x.Id > y.Id) return -1; else return 0; } }

    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;
        }
    }

For more info refere below http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html

참고URL : https://stackoverflow.com/questions/538096/when-to-use-icomparablet-vs-icomparert

반응형