2010-09-21 8 views
6
[Serializable] 
class MyClass 
{ 
    [NonSerialized] int Foo { get; set; } // error 
    [NonSerialized] int bar; // ok 
} 

¿Por qué no se permite?¿Por qué [NonSerialized] no funciona en las propiedades autoaplicadas?

que sé acerca de las soluciones tales como

  • implementar ISerializable
  • cambiar a XmlSerializer/XmlIgnore
  • de cambiar a una propiedad implementado manualmente-

La pregunta es específicamente qué es [NonSerialized] no permitido en las propiedades, pero permitido en los campos.

Respuesta

12

Las propiedades son en realidad métodos, no están serializadas por el proceso de serialización binario. Son los campos que se serializan. Por lo tanto, solo tiene sentido especificar NonSerialized en un campo.

+0

propiedades no son meros métodos. Semánticamente son una combinación de métodos y un campo de respaldo implícito. Y todos los serializadores en existencia sí ven el campo de respaldo. Por lo tanto, tiene sentido controlar la serialización del campo de respaldo implícito a través de su propiedad. –

+2

De hecho, en realidad son un par de métodos. Pero el campo de respaldo está implícito solo para las propiedades automáticas, y puede que no exista en absoluto para las propiedades normales. De todos modos, cuando se introdujo el atributo 'NonSerialized', las auto-propiedades no existían, por lo que no podrían haber tomado esa consideración en cuenta –

+1

Ok, y si fueran a hacer que NonSerialized fuera válido para las propiedades * now *, tendrían para diferenciar entre auto-propiedades y propiedades normales en la enumeración AttributeTargets. Lo cual creo que no se puede hacer sin romper la compatibilidad. Aceptado. –

3

Creo que este es un caso de control fino que requiere más esfuerzo de su parte. En otras palabras, una propiedad automática tendrá de forma predeterminada un campo de respaldo serializable. Si quiere algo diferente al predeterminado, no puede usar una propiedad automática.

Pensé que usar [field:NonSerialized] en contra de la propiedad podría funcionar, pero no es así. El # spec C no llama explícitamente la serialización del campo de respaldo, pero sí incluye este (10.7.3):

The following example: 
public class Point { 
    public int X { get; set; } // automatically implemented 
    public int Y { get; set; } // automatically implemented 
} 
is equivalent to the following declaration: 
public class Point { 
    private int x; 
    private int y; 
    public int X { get { return x; } set { x = value; } } 
    public int Y { get { return y; } set { y = value; } } 
} 

Así, el campo de soporte es serializable (el valor predeterminado).

0

Es posible que desee consultar IgnoreDataMemberAttribute si está utilizando WCF. Esto funciona en auto-propiedades.

funciona incluso si usted no marca todos los demás miembros como DataMember (que siempre me pareció ser un dolor) y la clase con DataContract

Cuestiones relacionadas