0

I am trying to compare multiple properties from the object but my code is only capable of comparing the degree property. When debugging in Visual Studio it appears that my code is completely missing the else statement. I would appreciate any tips.

class Student : IComparable 
{
    private string fName;
    private string lName;
    private string deg;
    private int gra;

    public Student(string firstName, string lastName, string degree, int grade)
    {
        fName = firstName;
        lName = lastName;
        deg = degree;
        gra = grade;
    }

    public override string ToString()
    {
        string var = lName + ", " + fName + " (" + deg + ") Grade: " + gra;
        return var;
    }

    public int CompareTo(object obj)
    {
        Student newStudent = obj as Student;

        if (this.deg.CompareTo(newStudent.deg) == 1)
        {
            return 1;
        }
        else if (this.deg.CompareTo(newStudent.deg) != 1)
        {
            return -1;
        }
        else //this is what my code is ignoring and not ordering by firstname as well
        {
            if (this.fName == newStudent.fName)
            {
                return 0;
            }
            else if (this.fName != newStudent.fName)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
    }
}
Owen Gibson
  • 1
  • 1
  • 2
  • 1
    You return 1 immediately if degrees are equal. That's likely not what you want. –  Oct 14 '17 at 06:37

3 Answers3

1

First answer to your question(why else part never gets executed) is already answered, that is, there is no third possibility of a condition which is either 1 or not 1.

If you are trying to sort by different properties and for example if first we want to sort by degree and then by fName then we can implement IComparer-

class Student : IComparer<Student>{

    /*
    codes
   */


    public int Compare(Student student1, Student student2)
   {
          if(student1.deg.Equals(student2.deg))  //if both degrees are same
          {
              return string.Compare(student1.fName , student2.fName); // then compare fName
          }
          else
              return string.Compare(student1.deg , student2.deg);


   }
}
0

You return 1 if this.deg.CompareTo(newStudent.deg) == 1 and return -1 if this.deg.CompareTo(newStudent.deg) != 1. Since the comparison either is, or is not, equal to 1, you never reach the remaining else.

Thus your code should look something like the following:

partial class Student : IComparable, IComparable<Student>
{
    public int CompareTo(object obj)
    {
        if (obj != null && obj.GetType() != GetType())
        {
            // From https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx#Remarks
            // The parameter, obj, must be the same type as the class or value type that implements this interface; otherwise, an ArgumentException is thrown.
            throw new ArgumentException(string.Format("Object must be of type {0}", GetType()));
        }
        return CompareTo((Student)obj);
    }

    public int CompareTo(Student newStudent)
    {
        if (object.ReferenceEquals(this, newStudent))
            return 0;
        else if (newStudent == null)
            // From https://msdn.microsoft.com/en-us/library/43hc6wht(v=vs.110).aspx#Remarks
            // By definition, any object compares greater than null, and two null references compare equal to each other.
            return 1;

        var cmp = this.deg.CompareTo(newStudent.deg);
        if (cmp != 0)
            return cmp;

        cmp = this.fName.CompareTo(newStudent.fName);
        if (cmp != 0)
            return cmp;

        // Compare additional members as required, return the first nonzero member comparison.

        // Finally return 0 if all member comparisons returned 0.
        return 0;
    }
}

Notes:

dbc
  • 104,963
  • 20
  • 228
  • 340
-1

In your code

if (this.deg.CompareTo(newStudent.deg) == 1)
{
    // do something
}
else if (this.deg.CompareTo(newStudent.deg) != 1)
{
    // do something
}
else 
{
    // do something
}

else statement will never be reached, because result can either be equal to 1 or not. And you are checking only 'deg' value. For example, you can check if they are equal like this:

public int CompareTo(object obj)
{
    if (obj == null)
    {
        return -1;
    }
    Student newStudent = obj as Student;
    // are equal
    if (deg.CompareTo(newStudent.deg) == 0 && 
        gra.CompareTo(newStudent.gra) == 0 &&
        lName.CompareTo(newStudent.lName) == 0 &&
        fName.CompareTo(newStudent.fName) == 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
Gor Asatryan
  • 904
  • 7
  • 24
  • Actually CompareTo returns "A value that indicates the relative order of the objects being compared", hence not only 0 or 1: https://learn.microsoft.com/en-us/dotnet/api/system.icomparable.compareto?view=netframework-4.8 – Viking Jun 13 '19 at 11:36