Pregunta

Tengo un gráfico de objeto bastante considerable que he serializado en un archivo a través del DataContractSerializer. Ahora quiero presentar una lista de estos archivos al usuario para elegir. En esta lista, quiero mostrar algunos de los detalles sobre el archivo, que son propiedades del objeto raíz. No quiero cargar todo el gráfico en la memoria, ya que solo estoy interesado en mostrar las propiedades del nodo raíz.

¿Alguien sabe una manera de controlar la " profundidad " de la deserialización para que pueda extraer el objeto raíz del archivo y omitir los elementos secundarios? Prefiero evitar tratar el archivo como XML sin procesar, ya que no estoy haciendo ninguna manipulación de XML sin procesar en ningún otro lugar, y esa sería una rama más del código que tengo que mantener sincronizado.

Mi única idea en este momento es crear un "resumen" compatible objeto que contiene solo las propiedades que me interesan, y ninguno de los hijos, y deserializar el archivo en eso. Esto debería omitir los elementos secundarios ya que no son relevantes para el objeto de resumen.

¿Hay una mejor manera de lograr esto?

Actualización / Aclaración : los atributos no son la respuesta que estoy buscando. Por un lado, evitarán el "extra". propiedades de terminar en el archivo cuando el objeto se serializó por primera vez.

Segundo, son más permanentes que lo que estoy tratando de hacer. Finalmente, quiero deserializar todo el archivo, pero no en este punto. Estoy tratando de mostrar una lista resumida de archivos que el usuario elegirá para importar. Durante la importación, voy a necesitar a todos los hijos y nietos. Es demasiado exagerado durante el paso 1. Estos son archivos potencialmente grandes, por lo que deserializar completamente varios de ellos solo para que pueda mostrar su información de encabezado no va a funcionar.

Espero que eso aclare cualquier confusión sobre la pregunta original.

¿Fue útil?

Solución

Esa es la forma en que quieres hacerlo. DataContractSerializer está diseñado para manejar esta situación, en la que tiene que escribir tipos que son conceptualmente iguales, pero diferentes tipos desde el punto de vista del CLR que desea serializar entre sí.

Dado eso, simplemente cree el objeto con el subconjunto similar de propiedades que desea serializar y pase ese tipo al DataContractSerializer.

Asegúrese de que en el "resumen" escriba que establezca las propiedades del atributo DataContract (así como cualquier atributo DataMember o atributos DataContract en los elementos secundarios que exponga), específicamente las propiedades Nombre y Espacio de nombres para reflejar el nombre y el espacio de nombres del tipo sin resumen (ya que estos deben coincidir) .

Otros consejos

Mi primera recomendación sería hacer la manipulación de XML si solo desea obtener algunos detalles del nodo raíz. Otra posibilidad, aunque no conozco las implicaciones de rendimiento, es utilizar las capacidades de control de versiones de DataContractSerializer para este problema. En su contrato de datos, marque todos los campos excepto los que necesitará en el resumen como Opcionales. Luego, copie el contrato de datos como otra clase, dejando de lado los campos opcionales. Deserialícese con el nuevo contrato de datos más pequeño.

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}

puedes controlar tu serialización usando atributos. lea más aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top