Разъяснение о obj.getClass() != getClass()
.
Этот оператор является результатом equals()
являющийся недружелюбным наследованием. JLS (спецификация языка Java) определяет это, если A.equals(B) == true
тогда B.equals(A)
должен также возвратиться true
. Если Вы опустите тот оператор наследующие классы, которые переопределяют equals()
(и изменяются, то его поведение) повредит эту спецификацию.
Рассматривают следующий пример того, что происходит, когда оператор опущен:
class A {
int field1;
A(int field1) {
this.field1 = field1;
}
public boolean equals(Object other) {
return (other != null && other instanceof A && ((A) other).field1 == field1);
}
}
class B extends A {
int field2;
B(int field1, int field2) {
super(field1);
this.field2 = field2;
}
public boolean equals(Object other) {
return (other != null && other instanceof B && ((B)other).field2 == field2 && super.equals(other));
}
}
Выполнение new A(1).equals(new A(1))
кроме того, new B(1,1).equals(new B(1,1))
результат выделяет верный, как это должно.
Это выглядит все очень хорошим, но посмотрите, что происходит, если мы пытаемся использовать оба класса:
A a = new A(1);
B b = new B(1,1);
a.equals(b) == true;
b.equals(a) == false;
, Очевидно, это неправильно.
, Если Вы хотите гарантировать симметричное условие. a=b, если b=a и вызов принципа замены Лисков super.equals(other)
не только в случае [1 113] экземпляр, но и проверка после на [1 114] экземпляр:
if (other instanceof B )
return (other != null && ((B)other).field2 == field2 && super.equals(other));
if (other instanceof A) return super.equals(other);
else return false;
, Который произведет:
a.equals(b) == true;
b.equals(a) == true;
, Где, если a
не ссылка [1 116], то это могло бы быть быть ссылкой класса A
(потому что Вы расширяете его), в этом случае Вы звоните super.equals()
также .
Вы загрузили одну и ту же сборку дважды в разных контекстах загрузчика . Например, вы случайно загрузили XXX.Auditing с помощью Assembly.LoadFrom ()
, а затем какая-то другая (или ваша) сборка загрузила его нормально. Фактически, двоичный десериализатор мог быть тем, кто загрузил сборку второй раз, хотя я не знаю почему (нет опыта работы с ASP.NET).
Мне кажется, что у вас один и тот же класс в разных сборках (или веб-приложениях). BinaryFormatter включает метаданные типа в сериализацию, что означает, что будет работать только такая же сборка . 2 решения:
Лично я бы выбрал второй для огромного количества Причины не ограничиваются только этой. Возможные варианты:
В конце концов, я думаю, моя проблема была связана с динамической загрузкой. Когда я реализовал его с помощью XmlSerializer, у меня возникла точно такая же проблема.
Решение заключалось в том, чтобы поместить классы, которые я хотел сериализовать, в отдельную сборку, чтобы они не загружались динамически.