2010-02-11 18 views
12

Dadas dos instancias de una clase, ¿es una práctica buena y confiable compararlas serializándolas primero y luego comparando matrices de bytes (o posiblemente hash de matrices)? Estos objetos pueden tener propiedades jerárquicas complejas, pero la serialización debe ser tan profunda como se requiera.¿Es confiable comparar dos instancias de una clase comparando sus matrices de bytes serializados?

En comparación me refiero al proceso de asegurar que todas las propiedades de los tipos primitivos tengan valores iguales, las propiedades de los tipos complejos tengan propiedades iguales de tipos primitivos, etc. En cuanto a las propiedades de recolección, deben ser iguales: iguales elementos, mismas posiciones:

{'a','b','c'} != {'a','c','b'} 



{new Customer{Id=2, Name="abc"}, new Customer {Id=3, Name="def"}} 
    != 
{new Customer{Id=3, Name="def"}, new Customer {Id=2, Name="abc"}} 

pero

{new Customer{Id=2, Name="abc"}, new Customer {Id=3, Name="def"}} 
    == 
{new Customer{Id=2, Name="abc"}, new Customer {Id=3, Name="def"}} 

y mediante la serialización me refiero formateador binario estándar de .NET.

Gracias.

+1

¿Con qué propósito le gustaría hacer este tipo de comparación? Eso podría ayudar a proporcionar una respuesta más detallada. – BlueMonkMN

+0

Actualmente conozco dos formas de comparar objetos (aquellos que no implementan IComparable o IEquattable), con PropertyInfo y PropertyDescriptor. Esto podría ser simplemente una tercera herramienta en mi kit de herramientas. Pero estoy interesado en la aplicabilidad general y la confiabilidad de este método. ¿Puede dar resultados incorrectos? – Valentin

Respuesta

5

Está solicitando una garantía de que la representación serializada coincidirá. Eso va a ser muy difícil de conseguir, BinaryFormatter es una clase complicada. Las estructuras particularmente serializadas que tienen relleno de alineación podrían ser un problema potencial.

Lo que es mucho más simple es proporcionar un ejemplo en el que no coincida. System.Decimal tiene diferentes patrones de bytes para valores como 0.01M y 0.010M. Su operador ==() dirá que son iguales, su byte serializado [] no lo hará.

2

Debería definir qué significa igual aquí con más precisión.

Si una de las propiedades es una colección, puede haber diferencias en el orden (como resultado de determinadas secuencias de Agregar/Eliminar) que pueden o no ser importantes para usted. Piensa en un diccionario donde se agregaron los mismos elementos en un orden diferente. Una colisión puede resultar en una secuencia binaria diferente.

2

Es fiable si:

  1. Cada clase única en el gráfico está marcada [Serializable]. Esto no es tan sencillo como podría parecer; si comparas objetos totalmente arbitrarios, entonces hay muchas posibilidades de que exista algo no serializable que no puedas controlar.

  2. Desea saber si las dos instancias son exactamente lo mismo. Tenga en cuenta que BinaryFormatter es básicamente sumergirse en el estado interno de estos objetos, por lo que incluso si parecen ser los mismos en virtud de las propiedades públicas, es posible que no lo sean. Si sabe a ciencia cierta que el gráfico se crea exactamente de la misma manera en cada caso, tal vez no le importe esto; pero si no, puede haber una serie de diferencias ocultas entre los gráficos.

    Este punto es también una arruga más grave de lo que uno podría sospechar. ¿Qué sucede si decides intercambiar la clase con una interfaz? Puede tener dos interfaces que, hasta donde sabe, son exactamente las mismas; cumplen la misma tarea y proporcionan los mismos datos. Pero pueden ser implementaciones totalmente diferentes. Lo bueno de IEquatable es que es independiente del tipo de concreto.

por lo que esto trabajo, para un número significativo de casos, pero probablemente no lo consideraría una buena práctica, al menos no sin conocer todos los detalles acerca del contexto específico que se está utilizando en Por lo menos, no confiaría en esto como un método de comparación genérico para any dos instancias; debe usarse solo en casos específicos en los que conozca los detalles de implementación de las clases involucradas.

Por supuesto, algunos podrían decir que escribir cualquier código que dependa de los detalles de implementación de una clase es siempre una mala práctica.Mi opinión sobre esto es más moderada, pero es algo a tener en cuenta: confiar en los detalles de implementación de una clase puede llevar a un código difícil de mantener más adelante.

+0

Con respecto al punto 1), un tipo no serializable en el gráfico emitirá una excepción. –

Cuestiones relacionadas