none
Перегрузка операторов сравнения RRS feed

  • Вопрос

  • Доброго времени суток!

    Возникла необходимость в перегрузке оператора == для сравнения двух матриц класса MATRIX (пользовательский) т.к. иначе разультат всегда false.

    но осталась нужда в проверке матрицы на null, чтобы не возникала ошибка вызова методов класса. Так вот, если я сравниваю две заданные матрицы, которые заведомо не null, то все нормально. А при попытке выполнить код if(matrix == null) возникает сообщение о неверном параметре

            public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
            {
                if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                {
                    throw new SizeExcept();
                }
                else
                {
                    for (int _row = 0; _row < left_matrix.Rows; ++_row)
                        for (int _col = 0; _col < left_matrix.Cols; ++_col)
                            if (left_matrix.matrix[_row, _col] != right_matrix.matrix[_row, _col])
                                return false;
                    return true;
                }
            }
            public static bool operator !=(Matrix left_matrix, Matrix right_matrix)
            {
                if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                {
                    throw new SizeExcept();
                }
                else
                {
                    for (int _row = 0; _row < left_matrix.Rows; ++_row)
                        for (int _col = 0; _col < left_matrix.Cols; ++_col)
                            if (left_matrix.matrix[_row, _col] == right_matrix.matrix[_row, _col])
                                return false;
                    return true;
                }
            }
    Если возможно, подскажите выход из данной ситуации.

    PS: И что делать с этими предупреждениями? При компиляции появляются, но жить вроде не мешают.

    Предупреждение 1 "LR_09.Matrix" определяет оператор == или оператор != , но не переопределяет Object.GetHashCode() 

    Предупреждение 2 "LR_09.Matrix" определяет оператор == или оператор != , но не переопределяет Object.Equals(object o)


    18 марта 2013 г. 5:27

Ответы


  • public override int GethashCode()

    return 0;

    //Если у вас будет коллекции матриц то придется выбрать какой либо свой алгоритм генерации хеш кода

    }


    а так почитайте про этот метод gethashcode и gethashcode

    про перегрузку оператором можно почитать вот тут Operator

    проверить на null можно вот таким способом

    object.ReferenceEquals(null, obj1)

    что то в таком стиле

    public static bool operator ==(Matrix m1, Matrix m2)
    {
        if (object.ReferenceEquals(null, m1))
            return object.ReferenceEquals(null, m2);
        return m1.Equals(m2);
    }



    18 марта 2013 г. 7:39

Все ответы

  • оператор == это аналог Equals переместите ваш код проверки с Equals и просто вызывайте его в операторах == и !=

    В начале оператора сравнение поставить проверку на null, если null возвращать false.

    Про GetHashCode сделайте перегрузку в которой вызывается базовый класс.

    18 марта 2013 г. 5:58
  • Основная проблема при проверке вашей матрицы на null, в том, что вы вызываете перегруженную опреацию, а она вызывает еще одну перегруженную операцию. Поэтому для проверки на null лучше воспользоваться Equel или написать вот так:

    public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
    {
        if ((object)left_matrix == null || (object)right_matrix == null)
        {
            throw new ArgumentNullException();
        }

    18 марта 2013 г. 6:48
    Отвечающий
  • Основная проблема при проверке вашей матрицы на null, в том, что вы вызываете перегруженную опреацию, а она вызывает еще одну перегруженную операцию. Поэтому для проверки на null лучше воспользоваться Equel или написать вот так:

    public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
    {
        if ((object)left_matrix == null || (object)right_matrix == null)
        {
            throw new ArgumentNullException();
        }

    Если matrix_A определена на момент вызова метода класса MATRIX (например: matrix_A.Print()), то проблем не возникает. Но если матрица еще null (т.е. переменная есть, но еще не заданы ее параметры), то тут появляется сообщение, что "ссылка на объект не указывает на экземпляр класса"

     Вот мне и хочется отработать условие if (matrix_A == null),  как стандартную проверку C#, а вместо этого вызывается перегруженный оператор из класса MATRIX и получаю сообщение, что передан неверный параметр


    18 марта 2013 г. 7:25
  • Про GetHashCode сделайте перегрузку в которой вызывается базовый класс.

    Подскажите как, пожалуйста!

    я что-то не сообразил как это сделать

    18 марта 2013 г. 7:27

  • public override int GethashCode()

    return 0;

    //Если у вас будет коллекции матриц то придется выбрать какой либо свой алгоритм генерации хеш кода

    }


    а так почитайте про этот метод gethashcode и gethashcode

    про перегрузку оператором можно почитать вот тут Operator

    проверить на null можно вот таким способом

    object.ReferenceEquals(null, obj1)

    что то в таком стиле

    public static bool operator ==(Matrix m1, Matrix m2)
    {
        if (object.ReferenceEquals(null, m1))
            return object.ReferenceEquals(null, m2);
        return m1.Equals(m2);
    }



    18 марта 2013 г. 7:39
  • Если matrix_A определена на момент вызова метода класса MATRIX (например: matrix_A.Print()), то проблем не возникает. Но если матрица еще null (т.е. переменная есть, но еще не заданы ее параметры), то тут появляется сообщение, что "ссылка на объект не указывает на экземпляр класса"

     Вот мне и хочется отработать условие if (matrix_A == null),  как стандартную проверку C#, а вместо этого вызывается перегруженный оператор из класса MATRIX и получаю сообщение, что передан неверный параметр


    Ну тогда вот такой код напишите:

    public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
    {
        if ((object)left_matrix == null && (object)right_matrix == null)
        {
            return true;
        }
        else if ((object)left_matrix == null || (object)right_matrix == null)
        {
            return false;
        }

    В этом случае, перегруженный оператор будет отрабатывать проверки null-ов корректно.
    18 марта 2013 г. 7:46
    Отвечающий

  • public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
    {
        if ((object)left_matrix == null && (object)right_matrix == null)
        {
            return true;
        }
        else if ((object)left_matrix == null || (object)right_matrix == null)
        {
            return false;
        }

    В этом случае, перегруженный оператор будет отрабатывать проверки null-ов корректно.

     Неправда! Происходит зацикливание на себя и переполнение стека

    Сделал так, как советовал BRASH_O

            public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(left_matrix, right_matrix))
                {
                    return true;
                }
                else if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                {
                    throw new SizeExcept();
                }
                else
                {
                    for (int _row = 0; _row < left_matrix.Rows; ++_row)
                        for (int _col = 0; _col < left_matrix.Cols; ++_col)
                            if (left_matrix.matrix[_row, _col] != right_matrix.matrix[_row, _col])
                                return false;
                    return true;
                }
            }
            public static bool operator !=(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(left_matrix, right_matrix))
                {
                    return false;
                }
                else if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                {
                    throw new SizeExcept();
                }
                else
                {
                    for (int _row = 0; _row < left_matrix.Rows; ++_row)
                        for (int _col = 0; _col < left_matrix.Cols; ++_col)
                            if (left_matrix.matrix[_row, _col] == right_matrix.matrix[_row, _col])
                                return false;
                    return true;
                }
            }
    

    теперь проверка матрицы на null проходит нормально

    Спасибо всем!!!

    18 марта 2013 г. 9:19

  •         public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(left_matrix, right_matrix))
                {
                    return true;
                }
                else if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                ... 
            }
            public static bool operator !=(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(left_matrix, right_matrix))
                {
                    return false;
                }
                else if ((left_matrix.Rows != right_matrix.Rows) || (left_matrix.Cols != right_matrix.Cols))
                ...
            }


     Подправил... так действительно работает четко

            public static bool operator ==(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(right_matrix, null))
                {
                    return object.ReferenceEquals(left_matrix, right_matrix);
                }
                else 
                ... 
            }
            public static bool operator !=(Matrix left_matrix, Matrix right_matrix)
            {
                if (object.ReferenceEquals(right_matrix, null)) 
                {
                    return !object.ReferenceEquals(left_matrix, right_matrix);
                }
                else 
                ... 
            }
    

    18 марта 2013 г. 10:32