typedef typename Tail::inUnion dummy;
Однако я не уверен, что реализация inUnion верна. Если я правильно понимаю, этот класс не должен быть создан, поэтому вкладка «fail» никогда не будет автоматически терпеть неудачу. Возможно, было бы лучше указать, находится ли тип в объединении или нет с простым булевым значением.
template
struct Contains; template struct Contains > { enum { result = Contains ::result }; }; template struct Contains > { enum { result = true }; }; template struct Contains { enum { result = false }; }; PS: Посмотрите на Boost :: Variant
PS2: посмотрите на typelists , особенно в книге Андрея Александреску: Modern C ++ Design
Если Вы действительно хотели добавить в белый список по причинам производительности, рассмотрите использование аннотации для указания который поля выдержать сравнение. Кроме того, эта реализация не будет работать, если Ваши поля не будут иметь хороших реализаций для equals()
.
P.S. Если Вы идете этим путем для equals()
, не забывайте делать что-то подобное для hashCode()
.
P.P.S. Я полагаю, что Вы уже рассмотрели HashCodeBuilder и EqualsBuilder.
Если Вы действительно идете отражательный подход, EqualsBuilder является все еще Вашим другом:
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
Используйте Eclipse, FFS!
Удалите хэш-код, и равняется методам, которые Вы имеете.
Щелкните правой кнопкой по файлу.
Выберите Источник->, Генерируют хэш-код, и равняется...
Готово! Больше никакого беспокойства об отражении.
Повторитесь для каждого добавленного поля, Вы просто используете представление схемы, чтобы удалить Ваши два метода и затем позволить Eclipse автоматически сгенерировать их.
Можно всегда аннотировать поля, которые Вы не хотите в Вашем, равняется методу, который должен быть простым и простым изменением в нем.
Производительность, очевидно, связана с тем, как часто объект на самом деле сравнен, но много карт хеша использования платформ, таким образом, Ваш равняется, может использоваться больше, чем Вы думаете.
Кроме того, говоря о картах хеша, у Вас есть та же проблема с методом хэш-кода.
Наконец, необходимо ли действительно сравнить все поля для равенства?
Вот мысль, если Вы волнуетесь по поводу:
1/, Забывающий обновить Вашу большую серию операторов "if" для проверки равенства, когда Вы добавляете/удаляете поле.
2/выполнение выполнения в этом равняние () метод.
Попробуйте следующее:
a/Возвращаются назад к использованию длинной последовательности операторов "if" в Вашем, равняется () методу.
b/Имеют единственную функцию, которая содержит список полей (в Массиве строк) и которая проверит что список по действительности (т.е. отраженные поля). Это выдаст исключение, если они не будут соответствовать.
c/В Вашем конструкторе для этого объекта, имейте синхронизируемое выполнение, после того как звонят в эту функцию (подобный шаблону "одиночка"). Другими словами, если это - первый объект, созданный этим классом, вызовите функцию проверки, описанную в (b) выше.
Исключение сделает его сразу очевидным, когда Вы запустите свою программу, если Вы не обновили свои операторы "if" для соответствия отраженным полям; затем Вы фиксируете операторы "if" и обновляете cписок полей от (b) выше.
Последующая конструкция объектов не сделает, эта проверка и Ваш равняются (), метод будет работать в, он - максимальная возможная скорость.
Попробуйте, как я мог бы, я не смочь найти любые настоящие проблемы с этим подходом (большие умы могут существовать на StackOverflow) - существует дополнительное условие, проверяют каждую объектную конструкцию для выполнения однажды поведение, но это кажется довольно незначительным.
Если Вы достаточно стараетесь, Вы могли бы все еще получить свои операторы "if" не в ногу с Вашим cписком полей и отразили поля, но исключение гарантирует, что Ваш cписок полей соответствует отраженным полям, и Вы просто удостоверяетесь, что обновляете операторы "if" и cписок полей одновременно.
У Вас есть несколько ошибок в Вашем коде.
this
и obj
тот же класс. Действительно, это явно допускается obj
быть любым другим классом. Вы могли запустить с if ( ! obj instanceof myClass ) return false;
однако это все еще не корректно потому что obj
мог быть подкласс this
с дополнительными полями, которые могли бы иметь значение.null
значения для obj
с простым if ( obj == null ) return false;
null
и пустая строка как равная. Вместо этого обработка null
особенно. Самый простой путь здесь состоит в том, чтобы запуститься путем сравнения Field.get(obj) == Field.get(this)
. Если они оба равны, или оба, оказывается, указывают на тот же объект, это быстро. (Отметьте: Это - также оптимизация, в которой Вы нуждаетесь, так как это - медленная стандартная программа.), Если это перестало работать, можно использовать быстрое if ( Field.get(obj) == null || Field.get(this) == null ) return false;
обработать случаи, где точно каждый null
. Наконец можно использовать обычное equals()
.foundMismatch
Я согласовываю с Hank это [HashCodeBuilder][1]
и [EqualsBuilder][2]
состоит в том, чтобы пойти лучший путь. Легко поддержать, не много шаблонного кода, и Вы избегаете всех этих проблем.
Вы могли использовать Аннотации для исключения полей из проверки
например.
@IgnoreEquals
String fieldThatShouldNotBeCompared;
И затем конечно, Вы проверяете, что присутствие аннотации в Вашем дженерике равняется методу.
Если у Вас есть доступ к названиям полей, почему Вы не делаете его стандартом, который поля, которые Вы не хотите включать всегда, запускают с "локального" или "nochk" или чего-то как этот.
Затем Вы помещаете в черный список все поля, которые начинаются с этого (код не так ужасен затем).
Я не сомневаюсь, что это немного медленнее. Необходимо решить, хотите ли Вы подкачать простоту обновлений против скорости выполнения.