2010-11-30 35 views
30
class Person 
{ 
    public string m_name; 
    private int m_age; // << how do I serialize the darn little rat? 
} 

Pregunta simple todavía parece un gran lío cuando se intenta responder.
Todos sugieren utilizar public getter/setter pero mi aplicación es demasiado grande y hacer un getter/setter para cada miembro solo causaría problemas de mantenimiento.C# serializar miembro privado de la clase

¿Estoy obligado a crear una serialización personalizada aquí o hay un atributo mágico para tales miembros?
¿Cómo serializo los miembros privados de la clase?

Edición # 1:
todos Ok, lo siento por la falta de claridad, que era un poco molesto cuando escribí esta pregunta, que era varias horas después de intentar encontrar la solución.
De todos modos, aquí hay más hechos:
1. Estoy tratando de XML serializar esta clase. Actualmente estoy usando System.Xml.Serialization.XmlSerializer.
2. Estoy serializando en XML para tener compatibilidad de versiones, que por lo que entiendo binario no me ofrece eso.
3.He tenía la esperanza de que hay una cierta atributo como:

class Person 
{ 
    public string m_name; 
    [SerializeThat(ElementName="Age")] 
    private int m_age; // << how do I serialize the darn little rat? 
} 

O (sigue del hecho # 3) un atributo que pasa en la clase la que se vería así:

[Serializable(DoPrivate = true, DoProtected = true)] 
class Person 
{ 
    public string m_name; 
    private int m_age; // << how do I serialize the darn little rat? 
} 

Ahora, ¿qué puedo hacer para lograrlo?

+2

Supongo public int m_age; debe ser privado? O bien, no hay problema, ¿verdad? –

+3

¿Qué tipo de serialización estás tratando de hacer? –

+0

¿Qué "gran desastre" está recibiendo? No veo por qué no puedes simplemente [Serializable] en la clase y terminar con eso. Tal vez hay algo por lo que está simplificando en su código de ejemplo que significa que está ocultando la causa del problema. –

Respuesta

17

Asumiendo un error tipográfico, me gustaría redirigirlo a this SO article donde la solución es usar un DataContractSerializer en su lugar.

+0

Hola Brad y gracias por la respuesta, ni siquiera puedo compilar el código, tal vez porque estoy tratando de hacerlo en una aplicación web ASP.NET? – Poni

+0

¿Cuáles son los errores de compilación? Voy a ver si Puedo ayudar. –

+0

Lo de siempre: "error CS0246: No se pudo encontrar el tipo o el nombre del espacio de nombres 'DataMember'." Weird. – Poni

8

Si usa BinaryFormatter, se destinará a las partes privadas de su clase.

Marca todas las clases de los suyos con [Serializable] o no ir muy lejos ...

También, mirar esto: Why is Serializable Attribute required for an object to be serialized

Ya que se necesita XML, tal vez usted puede tirarse a pesar de que todos con SoapFormatter. Ver this.

Compatibilidad con la versión a propósito: utilizo BinaryFormatter y no tengo problemas con las actualizaciones del esquema. Pruébelo: puede manejar los cambios de esquema usted mismo, simplemente reemplace los punteros nulos omitidos por el Deserialize con las construcciones predeterminadas apropiadas. Si realmente no necesita las características que proporciona XML, vaya binario; nunca mirará hacia atrás.

También, uno más EDIT:

BF resolverá fácilmente todas sus múltiples referencias por lo que no va a crear varias instancias de la misma referencia una y otra vez. Supongo que no obtendrá eso con XmlSerializer; es obvio que no tiene lugar para almacenar esa información.

Ejemplo:

class Data 
{ 
    int a; 
} 

class ManyData 
{ 
    Data d1; 
    Data d2; 
} 

... 

ManyData md=new ManyData(); 
md.d1=new Data(); 
md.d2=md.d1; 

Trate de serialización/deserialización md con varias alternativas ...

+0

Nononno, está bien. Yo uso BF todo el tiempo, y vivimos en un matrimonio feliz :) –

+1

@Daniel - no todos los matrimonios terminan bien. No soy ** un ** fanático de BF –

+0

@Marc, ¿qué pasa? –

6

No sé si puede usar DataContract. Pero con esto se podría escribir:

[DataContract] 
class Person 
{ 
    [DataMember] 
    public string m_name; 

    [DataMember] 
    private int m_age; 
} 

La ventaja de DataContract que se puede serializar campos privados y su clase no necesita un constructor por defecto.

+0

Gracias también. Estoy revisando esto mientras estamos hablando. – Poni

+0

Buena respuesta Oliver, gracias. Ojalá lo fraseras de forma diferente, eso me ahorraría tiempo (: – Poni

+0

Si no se requiere un manejo personalizado (como la exclusión), esto podría ser incluso más simple, solo tienes el atributo 'Serializable' y DataContractSerializer ahora elegirá todos los miembros de la clase sin tener que marcarlos con '[DataMember]' – nawfal

5

Qué comió serializador que actualmente usando? Casi todos deberían trabajar con eso. Pero los campos públicos * es * una mala idea. XmlSerializer y JavaScriptSerializer ignorarán los miembros privados. DataContractSerializer y protobuf-net pueden tratar con miembros privados. BinaryFormatter maneja campos (público o privado), pero no es una buena idea IMO por varias razones.

+0

Marc gracias por tomarse el tiempo para responder - como he escrito en la edición n. ° 1, intento XML serializar esta clase. Además, 'DataContractSerializer' no parece existir en una aplicación web ASP.NET. Usando VS2008. ¿Qué puede decir? – Poni

+0

@Poni - agregue una referencia a System.Runtime.Serialization.dll –

+0

'XmlSerializer' existe sin esa referencia ... Un pequeño atributo que falta tanto dolor:/ – Poni

Cuestiones relacionadas