Search code examples
c#methodsicomparable

C#: Is it possible for the compiler to auto-call a method?


In this code, the CompareTo() method is not called explicitly and the max() gives the correct result. So, my question is: Is it possible that CompareTo() is called implicitly/auto-call? If so, how would I know which other function/method could be called implicitly? Please help me understand, thank you! Results : Steve

public class Student : IComparable<Student> 
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int Age { get; set; }
    public int StandardID { get; set; }

    public int CompareTo(Student other)
    {
        if (this.StudentName.Length >= other.StudentName.Length)
        return 1;

        return 0;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Student collection
        IList<Student> studentList = new List<Student>>() { 
                new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
                new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
                new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
                new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
                new Student() { StudentID = 5, StudentName = "Steve" , Age = 15 } 
            };
        var studentWithLongName = studentList.Max();

        Console.WriteLine("Student Name: {1}", studentWithLongName.StudentName);

    }
}

Solution

  • As Jeroen already said, you are making a call to the IEnumerable.Max() method.

    Basically what that function is doing "in the shadows" is something similar to this:

    private static T Max<T>(IEnumerable<T> source) where T : IComparable<T>
    {
      if (source == null)
        throw new ArgumentNullException(nameof(source));
    
      bool isMaxSet = false;
      T max;
      foreach (T item in source)
      {
        if (isMaxSet == false)
        {
          max = item;
          isMaxSet = true;
        }
        else
        {
          if (max.CompareTo(item) < 0) // here's where it's used!
            max = item;
        }
      }
    
      if (isMaxSet == false)
        throw new InvalidOperationException();
    
      return max;
    }
    

    Also, be careful as your int CompareTo(Student) function is incomplete and its use could cause unexpected results.

    As specified in https://learn.microsoft.com/en-us/dotnet/api/system.icomparable.compareto?view=netframework-4.8, here's how it should work:

    Less than zero: This instance precedes obj in the sort order.

    Zero: This instance occurs in the same position in the sort order as obj.

    Greater than zero: This instance follows obj in the sort order.