Должен IEquatable <T>, IComparable <T> быть реализованным на незапечатанных классах?

mmap модуль Python позволит Вам вставлять в файл. Следующий образец показывает, как он может быть сделан в Unix (Windows mmap может отличаться). Обратите внимание, что это не обрабатывает все состояния ошибки, и Вы могли бы повредить или потерять исходный файл. Кроме того, это не обработает строки unicode.

import os
from mmap import mmap

def insert(filename, str, pos):
    if len(str) < 1:
        # nothing to insert
        return

    f = open(filename, 'r+')
    m = mmap(f.fileno(), os.path.getsize(filename))
    origSize = m.size()

    # or this could be an error
    if pos > origSize:
        pos = origSize
    elif pos < 0:
        pos = 0

    m.resize(origSize + len(str))
    m[pos+len(str):] = m[pos:origSize]
    m[pos:pos+len(str)] = str
    m.close()
    f.close()

также возможно сделать это без mmap с файлами, открытыми в 'r +' режим, но это менее удобно и менее эффективно, поскольку необходимо было бы считать и временно сохранить содержание файла от положения вставки до EOF - который мог бы быть огромным.

36
задан casperOne 6 October 2011 в 03:24
поделиться

2 ответа

Я немного подумал над этим вопросом и после небольшого размышления согласен с тем, что реализация IEquatable и IComparable должна выполняться только на запечатанные типы.

Я немного ходил туда-сюда, но потом подумал о следующем тесте. При каких обстоятельствах следующее должно возвращать false? ИМХО, 2 объекта либо равны, либо нет.

public void EqualitySanityCheck<T>(T left, T right) where T : IEquatable<T> {
  var equals1 = left.Equals(right);
  var equals2 = ((IEqutable<T>)left).Equals(right);
  Assert.AreEqual(equals1,equals2);
}

Результат IEquatable для данного объекта должен иметь то же поведение, что и Object.Equals , при условии, что компаратор имеет эквивалентный тип. Двойная реализация IEquatable в иерархии объектов позволяет и подразумевает, что существует 2 различных способа выражения равенства в вашей системе. Это' Легко придумать любое количество сценариев, в которых IEquatable и Object.Equals будут различаться, поскольку существует несколько IEquatable реализаций, но только одна Object.Equals . Следовательно, приведенное выше приведет к ошибке и создаст некоторую путаницу в вашем коде.

Некоторые люди могут возразить, что реализация IEquatable на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer , который специально разработан для сравнения этих свойств.

, но только один Object.Equals . Следовательно, приведенное выше приведет к ошибке и создаст некоторую путаницу в вашем коде.

Некоторые люди могут возразить, что реализация IEquatable на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer , который специально разработан для сравнения этих свойств.

, но только один Object.Equals . Следовательно, приведенное выше приведет к ошибке и вызовет некоторую путаницу в вашем коде.

Некоторые люди могут возразить, что реализация IEquatable на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer , который специально разработан для сравнения этих свойств.

, который специально разработан для сравнения этих свойств.

, который специально разработан для сравнения этих свойств.

20
ответ дан 27 November 2019 в 06:16
поделиться

Большинство реализаций Equals , которые я видел, проверяют типы сравниваемых объектов, если они не совпадают, метод возвращает false.

Это аккуратно. позволяет избежать проблемы сравнения подтипа с его родительским типом, тем самым устраняя необходимость герметизации класса.

Очевидным примером этого может быть попытка сравнения двухмерной точки (A) с трехмерной точкой (B). : для 2D значения x и y 3D-точки могут быть равны, но для 3D-точки значение z, скорее всего, будет другим.

Это означает, что A == B будет правда, но B == A будет ложью. Большинству людей нравится, что операторы Equals являются коммутативными, в этом случае проверка типов явно является хорошей идеей.

Но что, если вы создаете подклассы, а не не добавить новые свойства? Что ж, на этот вопрос ответить немного сложнее и, возможно, зависит от вашей ситуации.

1
ответ дан 27 November 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: