What des it mean by the following sentence
DependencyObjects are not marked as serializable
To my knowledge, I can have a class which inherits from DependencyObject...and I can mark it as serializable. Anyway serialize property is not inheritable.
Could someone make me clear. Thanks in advance.
This means that a class that derives from DependencyObject cannot be serialized with standard serializers. As a workaround you could use XamlReader/XamlWriter as shown in this article.
DependencyObject exists to make use of the entire dependency property system. One side effect of this is that it really doesn't mesh with the approach to serialization taken in .NET.
Serialization, in .NET, serializes fields in a class. However, DependencyObjects don't actually use (instance) fields, but rather registered DependencyProperties, which are stored elsewhere (if at all). As such, they don't serialize properly, even if you mark them [Serializable].
Related
I have a class which i am serializing. I annotated it with [Serializable] and i am using binary serializer. Everything works fine.
But later i introduced new properties, which cannot be serialized (lets say they contain a lot of mess about GUI which does not need to be rembered). I can compute these properties based on other properties of class.
I need to do it two times, when I serialize - clean mess and enter stabile state ready for serialization. And deserialization - again compute all needed properties.
I need to react on 'events' instance is being serialized/deserialized.
However I can't find these events because I am not implementing the interface ISerializable or abstract class Aserializable but only class atribute [Serializable].
I do not know when class is being serialized because it is not the concern of this class; it is serialized as a field of another class.
Is there a way I can react on those events?
You can use OnDeserializedAttribute and its related attributes (OnSerializing, OnSerialized, OnDeserializing) to create special methods that are called during the serialization/deserialization process.
Build Custome Serialization by Implementing ISerializable. Use OnSerializingAttribute, to manipulate object before serilazation and OnDeserializingAttribute, to manipulate before deserialization.
Have you considered per chance the [XmlIgnoreAttribute] attribute? It will prevent a property to be serialized. No need to tamper withe the serialization workflow.
My bad, didn't realize you wanted to reload some property on deserialization. So why not serialize these? In an optional subObject, or whatever?
I need to serialize a collection, but I would like to know if there is any already serializable collection before taking code from third parts or write it by myself. I already implemented some serializable collection, but this is a stupid situation where I just need to pass an array of serializable classes to the clipboard and back from it (copy/paste).
Any suggestion on what should I use?
Any class in the System.Collections or System.Collections.Generic namespace should be serializable. However, this doesn't mean that the content (or in the case of generics, T is serializable). This is visible with Dictionary<K,V>, as KeyValuePair<K,V> isn't directly serializable.
I used List<T> before and it works great.
My objects has a parent-child relationship. Each child object has a Parent property pointing to its container. When this object is created in the app, it's set, and thus no problem. This Parent property is marked with XmlIgnore attribute, because it needs to be set to its run-time parent instance. So, what's the best way to initialize this Parent property after the object is deserialized? Is there a 'Deserialize completed' event or something similar?
EDIT: I'm talking about XmlSerializer in C# WPF. I don't want binary serializer.
Your question is somewhat lacking in details, but from some of the attributes and properties that you describe, I'm going to assume that you're using the XMLSerializer in the .NET Framework.
You may know about the OnDeserialized attribute, which you can use to mark a particular method that you want to be called after an object has been deserialized. Unfortunately, this only works with the Binary, SOAP, and DataAttribute formatters, not for XMLSerializer.
In order to achieve this same functionality using the XMLSerializer, you will have to implement the IXmlSerializable interface yourself on the class that you want to serialize to XML. This will allow you to complete control over how instances of your class are serialized and deserialized, including code that is run to initialize the Parent property after an object is deserialized.
There is a good example article on CodeProject that describes how to correctly implement IXmlSerializable available here.
XmlSerializer does not provide serialization callbacks, I'm afraid. One way to do this is for the parent to handle this when adding - but you will need a custom collection (perhaps inherited from Collection<T>) that during Add/Remove calls some method on the child to add (or remove, if removing from the collection) the parent.
Alternatively - consider simply making it a one-way only tree - i.e. the child doesn't have a parent property.
Another option is simply to walk the model through code after deserialization, and fixup any parent values.
The final option is to implement IXmlSerializable, but that is very hard get right.
Seeing as you can convert any document to a byte array and save it to disk, and then rebuild the file to its original form (as long as you have meta data for its filename etc.).
Why do you have to mark a class with [Serializable] etc? Is that just the same idea, "meta data" type information so when you cast the object to its class things are mapped properly?
Binary serialization is pretty powerful, it can create an instance of a class without running the constructor and can set fields in your class that you declared private. Regular code can of course not do this. By applying the [Serializable] attribute, you explicitly give it the go-ahead to mess with your private parts. And you implicitly give that permission to only the BinaryFormatter class.
XML serialization doesn't need this kind of okay, it only serializes members that are public.
DataContractSerializer can serialize private members as well. It therefore needs an explicit okay again, now with the [DataContract] attribute.
First off, you don't have to.
It is simply a marker interface that tells the serializer that the class is composed of items that it can serialize (which may or may not be true) and that is can use the default serialization.
The XMLSerializer has the additional requirement to have a zero parameter constructor to the class.
There are other serializers that use contracts for serialization (such as the DataContractSerializer) - they give you more control over serialization than simply marking a class as Serializable. You can also get more control by implementing the ISerializable interface.
It's basically metadata that indicates that a class can be serialized, nothing more.
It is required by a lot of framework serializers, which refuse to deal with types not having this attribute applied to them.
Serialization can create security holes and may be plagued by versioning problems. On top of that, for some classes, the very idea of serialization is outright nonsense.
For details, see the excellent answers to Why Java needs Serializable interface?, especially this one, this one, and this one. They make the case that serialization should be a feature you have to explicitly opt into.
For a counterpoint, the accepted answer to that question makes the case that classes should be serializable by default.
It indicates to the serializer that you want that class to be serialized as you may not want all properties or classes to be serialized.
I see it as a reminder that I will allow the class to be serialized. So you don't implicitly serialize something you shouldn't.
Don't know it that is designers' intention.
BTW, I just love BinaryFormatter and use it as much as I can. It handles pretty much of the stuff automatically (like rebuilding complex object graphs with recurring references spread throughout the graph).
I have read that private variables in a base class are technically inherited by child classes, but are not accessible.
If this is correct, why do we say they are inherited when presumably they can only be accessed by reflection?
Subclassing is about inheriting implementation; and fields are an implementation detail.
The fields are indeed present, and are available via reflection. But ultimately, it is the base-classes job to manage the state of those fields via any public/protected/etc members.
But ultimately - if a base-class declares a property (and field) for property Foo, then when you set that property the data has to go somewhere. The sub-class has to include all the fields from the base-class for it to make sense. This is also critical for field-based serialization frameworks (such as BinaryFormatter).
Private fields are inherited in the sense, that they take up space on the heap when allocated. However, the derived class cannot access them directly.
why do we say they are inherited...
Personally, I don't. I consider inheritance to include those things that you can access in a child class, not those things that are hidden.
I could see someone saying that to be clear that inheritance includes all elements up the chain, but it strikes me as overly pedantic and not especially useful.