Сопоставимое сравнение целого числа с объектом, приведение не сработало

#c#

#c#

Вопрос:

Это часть задания по науке о данных, мы не получаем оценок, просто нужно понять, что здесь происходит. Я занимался этим 10 часов подряд, и мой TA вчера отказался от меня, так что ты мой последний шанс :-/

Я изучаю IComparable интерфейс. В связи с этим у меня есть класс, ComparisonCountedInt и его единственной задачей должно быть взять целое число (в конструкторе), наследовать IComparable и иметь общедоступный статический метод, который будет подсчитывать количество раз, когда ComparisonCountedInt[] сравнивался с помощью двоичного поиска.

При запуске приведенного ниже кода я получаю System.ArgumentException :

Система.Исключение ArgumentException : otherObj НЕ СОПОСТАВИМ
в библиотеке.ComparisonCountedInt.compareTo(другой объект)

Я также пытался преобразовать объект в int, но это тоже не сработало.

Ниже приведен мой код:

 public class ComparisonCountedInt : IComparable
{
    // Holds the integer sat in the constructor
    public int Number;

    // Counter to see how many comparisons are made
    public int ComparisonCount { get; set; }

    // Input an integer
    public ComparisonCountedInt(int number)
    {
        this.Number = number;
        this.ComparisonCount = 0;
    }

    /// <summary>
    /// Should compare this.Number with another instances Number
    /// </summary>
    /// <param name="other">other is an object,  
    /// but we want to cast it to an integer</param>
    public int CompareTo(object other)
    {
        if (other != null)
        {
            this.ComparisonCount  ;
            ComparisonCountedInt otherObj = other as ComparisonCountedInt;

            if (otherObj != null)
            {
                if (this.Number > otherObj.Number)
                {
                    return 1;
                }
                else if (this.Number == otherObj.Number)
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            throw new ArgumentException("otherObj IS NOT COMPARABLE");
        }
        else
        {
            throw new ArgumentException("other IS NOT COMPARABLE");
        }
    }

    /// <summary>
    /// Count how many comparisons that have been made
    /// (Uses Binary Search to compare the array)
    /// </summary>
    public static int CountComparisons(ComparisonCountedInt[] array)
    {
        int sum = 0;

        for (int i = 0; i < array.Length; i  )
        {
            sum  = array[i].ComparisonCount;
        }
        return sum;
    }
}
  

Приведенный ниже код может вам и не понадобиться, но я подумал, что предоставлю все, что я вызываю / использую в рассматриваемом классе.

Чтобы воспроизвести / протестировать это, я использую тест NUnit:

 [TestFixture]
public class RunningTime
{
    private IComparable[] _myArray;

    private readonly ComparisonCountedInt[] _comparisonCountedIntArray =
    {
        new ComparisonCountedInt(1),
        new ComparisonCountedInt(2),
        new ComparisonCountedInt(5),
        new ComparisonCountedInt(6),
        new ComparisonCountedInt(8)
    };

    [TestCase]
    public void TestRunTime()
    {
        // Reset the counter
        var comparisons = ComparisonCountedInt.CountComparisons(_comparisonCountedIntArray);
        comparisons = 0;

        Search.Binary((IComparable[]) _comparisonCountedIntArray,
            (IComparable) _comparisonCountedIntArray[2]);

        // Comparisons should be less or equal to base2
        var base2 = ((int)Math.Ceiling(Math.Log(_comparisonCountedIntArray.Length, 2.0)));

        Console.WriteLine("Comparisons: {0}", comparisons);
        Console.WriteLine("base2: {0}", base2);

        Assert.GreaterOrEqual(base2, comparisons);
    }
}
  

И доставленный двоичный поиск, который использует compareTo (нам пришлось внести коррективы):

 public static class Search
{
    public static int Binary(IComparable[] array, IComparable target)
    {
        // Checking if array is empty
        if (array.Length == 0)
        {
            return -1;
        }

        // Checking if array is out of bounds
        if ((target.CompareTo(array[0]) <= 0) || (target.CompareTo(array.Length) >= 0))
        {
            return -1;
        }

        var low = 0;
        var high = array.Length - 1;

        // Binary search loop starts here
        while (low <= high)
        {
            var mid = low   (high - low) / 2; // var mid = (high   low) / 2;
            var midVal = array[mid];
            var relation = midVal.CompareTo(target);

            if (relation < 0)
            {
                low = mid   1;
            }
            else if (relation > 0)
            {
                high = mid - 1;
            }
            else if (low != mid)
            {
                //Equal but range is not fully scanned
                high = mid; //Set upper bound to current number and rescan
            }
            else
            {
                return mid;
            }
        }

        return -1;
    }
}
  

Комментарии:

1. Поместите еще немного отладочной информации там, где вы throw new ArgumentException("otherObj IS NOT COMPARABLE"); — попробуйте проверить, какой тип otherObj на самом деле, например. Вы также могли бы просто установить там точку останова и посмотреть, что происходит с отладчиком.

2. Мы еще не узнали об отладчиках, но я думаю, сейчас самое время! Спасибо!

3. Возможно, потребуется 5 минут, чтобы узнать, что вам нужно для начала: Навигация по коду с помощью Step Debugger

4. Определенно! В будущем вы потратите много времени в отладчике 🙂 Используете ли вы Visual Studio?

5. Вместо того, чтобы делать все if (this.Number > otherObj.Number) return 1; вещи, вы можете просто сделать return this.Number.CompareTo(otherObj.Number);