¿Cuál es el punto de la interfaz ISerializable?
-
03-07-2019 - |
Pregunta
Parece que puedo serializar clases que no tienen esa interfaz, por lo que no tengo claro su propósito.
Solución
ISerializable
se usa para proporcionar una serialización binaria personalizada, generalmente para BinaryFormatter
(y quizás para fines de comunicación remota). Sin él, utiliza los campos, que pueden ser:
- ineficiente; si hay campos que solo se usan para la eficiencia en el tiempo de ejecución, pero se pueden eliminar para la serialización (por ejemplo, un diccionario puede verse diferente cuando se serializa)
- ineficiente; ya que incluso para los campos que se necesitan, debe incluir una gran cantidad de metadatos adicionales
- no válido; si hay campos que no pueden ser serializados (como los delegados de eventos, aunque pueden marcarse como
[NonSerialized]
) - quebradizo; su serialización ahora está vinculada a los nombres de campo , pero los campos deben ser un detalle de implementación; vea también Ofuscación, serialización y propiedades implementadas automáticamente
Al implementar ISerializable
, puede proporcionar su propio mecanismo de serialización binario. Tenga en cuenta que el equivalente xml de esto es IXmlSerializable
, tal como lo utiliza XmlSerializer
etc.
Para propósitos de DTO, se debe evitar BinaryFormatter
- cosas como xml (a través de XmlSerializer
o DataContractSerializer
) o json son buenos, ya que están en cruz - Formatos de plataforma como los buffers de protocolo.
Para completar, protobuf-net incluye ganchos para ISerializable
(lo que le permite usar un formato binario portátil sin escribir mucho código), pero BinaryFormatter
no sería tu primera opción aquí de todos modos.
Otros consejos
Las clases se pueden serializar en .NET de una de estas dos formas:
- Marcar la clase con
SerializableAttribute
y decorar todos los campos que no quiere que se serialicen con el atributoNonSerialized
. (Como señala Marc Gravell,BinaryFormatter
, que es la clase que normalmente se usa para formatear objetos deISerializable
, serializa automáticamente todos los campos a menos que estén marcados específicamente de otra manera). - Implementando la interfaz
ISerializable
para una serialización totalmente personalizada.
El primero es más fácil de usar, ya que simplemente implica marcar declaraciones con atributos, pero tiene un poder limitado. Este último permite más flexibilidad pero requiere un esfuerzo significativamente mayor para implementar. Cuál debes usar depende completamente del contexto.
Con respecto a este último ( ISerializable
) y su uso, he citado de página MSDN para la interfaz:
Cualquier clase que pueda ser serializada debe estar marcado con el SerializableAttribute. Si una clase Necesita controlar su serialización. proceso, puede implementar el Interfaz iserializable. El formateador llama a GetObjectData al tiempo de serialización y rellena el suministró SerializationInfo con todos los datos requeridos para representar la objeto. El formateador crea un SerializationInfo con el tipo de Objeto en la gráfica. Objetos que necesitan para enviar proxies por sí mismos pueden usar el FullTypeName y AssemblyName Métodos en SerializationInfo para cambiar La información transmitida.
En el caso de herencia de clase, Es posible serializar una clase que deriva de una clase base que Implementa ISerializable. En esto caso, la clase derivada debe llamar la implementación de la clase base de GetObjectData dentro de su Implementación de GetObjectData. De lo contrario, los datos de la base. La clase no será serializada.
Con ISerializable
puede escribir métodos personalizados en su objeto para controlar la serialización al realizar una serialización binaria, para serializar sus objetos de una manera diferente a la que haría el enfoque predeterminado utilizado por BinaryFormatter.
En otras palabras, si el enfoque predeterminado serializa su objeto de una manera diferente a la forma en que desea que se serialice, puede implementar ISerializable para un control completo. Tenga en cuenta que de la mano con ISerializable, también hay un constructor personalizado que debe implementar.
XmlSerialization, por supuesto, solo usará propiedades, ISerializable no tiene nada que ver con la serialización XML.
Gracias, Marc y Pop por los comentarios, me apresuré un poco con mi primera respuesta.
Para hacer un objeto " transportable " ;, tienes que serializarlo. Por ejemplo, si desea transferir datos de objetos utilizando .NET Remoting o Web Services, debe proporcionar métodos que serialicen sus datos de objetos, reduciendo sus instancias de objetos a un formato transportable que represente una representación de alta fidelidad del objeto.
También puede tomar la representación serializada, transportarla a otro contexto, como una máquina diferente, y reconstruir su objeto original.
Al implementar la interfaz ISerializable
, una clase debe proporcionar el método GetObjectData que se incluye en la interfaz, así como un constructor especializado que está especializado en aceptar dos parámetros: una instancia de SerializationInfo, y una instancia de StreamingContext.
Si sus clases no requieren un control detallado de su estado de objeto, entonces podría usar el atributo [Serializable]
. Las clases que requieren más control sobre el proceso de serialización pueden implementar la interfaz ISerializable.