¿Qué pasa con el atributo ?

Como lo entiendo, tengo que adornar a un nuevo miembro en una versión más nueva de mi clase con el atributo [OptionalField] cuando deserializo una versión más antigua de mi clase que carece de este miembro más nuevo.

Sin embargo, el siguiente código no genera ninguna excepción mientras se agregó la propiedad InnerTranslator después de serializar la clase. Verifico que la propiedad sea nula en el método onDeserialization (que confirma que no fue serializado), pero hubiera esperado que el código arrojara una excepción debido a eso. ¿Es el atributo [OptionalField] en sí mismo opcional?

class Program { static void Main(string[] args) { var listcol = new SortedList { {"Estados Unidos", "United States"}, {"Canadá", "Canada"}, {"España", "Spain"} }; var translator = new CountryTranslator(listcol); using (var file_stream=new FileStream("translator.bin",FileMode.Open)) { var formatter = new BinaryFormatter(); translator = formatter.Deserialize(file_stream) as CountryTranslator; file_stream.Close(); } Console.ReadLine(); } } [Serializable] internal class CountryTranslator:IDeserializationCallback { public int Count { get; set; } public CountryTranslator(SortedList sorted_list) { this.country_list = sorted_list; inner_translator = new List {"one", "two"}; } //[OptionalField] private List inner_translator; public List InnerTranslator { get { return inner_translator; } set { inner_translator = value; } } private SortedList country_list; public void OnDeserialization(object sender) { Debug.Assert(inner_translator == null); Count=country_list.Count; } } 

BinaryFormatter es, en el mejor de los casos, muy frágil si cambias las cosas. No menos importantes, hay enormes problemas con las propiedades implementadas automáticamente, ofuscación , cambio de nombre, nombres fuertes, etc.

Como recuerdo, algunas de las reglas acerca de [OptionalField] cambiaron justo antes de su lanzamiento; La versión tolerante a la versión no funcionó tan fácilmente como se había planeado, supongo.

Mi consejo: si desea una serialización tolerante a la versión (es decir, puede serializarla hoy y deserializarla con la próxima versión de su aplicación), entonces no use BinaryFormatter ; esto es (IMO) solo adecuado para pasar datos entre la misma versión (comunicación remota, AppDomain , etc.).

Para el trabajo entre versiones, recomiendo la serialización basada en contrato; cosas como XmlSerializer y DataContractSerializer (.NET 3.0), o para binario – protobuf-net o herramientas similares. Todos estos son mucho mejores en la tolerancia de versión (de hecho, ni siquiera es necesario deserializarlo en el mismo Type ); además, se pueden usar entre plataformas, por lo que puede serializar en .NET y deserializar en java / C ++ / etc.