|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionIf you want to know how to get your application to save information to disk or the registry, then a quick skim through MSDN magazine or a quick search on newsgroups will give you the answer: serialization. Mark your classes with the All very simple, but unfortunately all very wrong. There are a number of reasons why you should not opt for the simple approach. Here are nine important ones. 1. It forces you to design your classes a certain wayXML serialization only works on public methods and fields, and on classes with public constructors. That means your classes need to be accessible to the outside world. You cannot have private or internal classes, or serialize private data. In addition, it forces restrictions on how you implement collections. 2. It is not future-proof for small changesIf you mark your classes as You can get around this by implementing the ISerializable interface. This gives you much better control of how data is serialized and deserialized. Unfortunately … 3. It is not future-proof for large changesType information is stored as part of the serialization information. If you change your class names or strong-name your assemblies, you’re going to hit all sorts of problems. Even if you manage to code the necessary contortions to get round this, you’re going to find that … 4. It is not future-proof for massive changes.NET isn’t going to be around in five years or so. If you start implementing the 5. It is not secureUsing XML serialization is inherently insecure. Your classes need to be public, and they need to have public properties or fields. In addition, XML serialization works by creating temporary files. If you think you’re creating temporary representations of your data (for example, to create a string that you’re going to post to a web service), then files on disk will pose a potential security risk. If, instead, you implement the 6. It is inefficientXML is verbose. And, if you are using the ISerializable interface, type information gets stored along with data. This makes serialization very expensive in terms of disk space. 7. It is a black boxThe odds are you don’t really know how serialization works. I certainly don’t. This means that there are going to be all sorts of quirks and gotchas that you can’t even conceive of when you start using it. Did you know that XML serialization actually uses the 8. It is slowWhen I did some research for a previous article (http://www.devx.com/dotnet/Article/16099/0), I noticed a few interesting things. I wrote a class that contained two double values. I created 100,000 instances of this class, stored them to disk, and then read them back again. I did this two ways. First of all, I did it the “proper” way, by implementing ISerializable, creating a BinaryFormatter, and using the 9. It is weird
using System;
using System.Runtime.Serialization;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
class Class1
{
static void Main(string[] args)
{
ParentClass c1=new ParentClass();
BinaryFormatter f=new BinaryFormatter();
MemoryStream m=new MemoryStream();
f.Serialize(m, c1);
m.Seek(0, SeekOrigin.Begin);
ParentClass newClass=(ParentClass)f.Deserialize(m);
Console.WriteLine("Deserialized\r\n{0}", newClass.ToString());
Console.WriteLine("Press [Enter]");
Console.ReadLine();
}
}
[Serializable]
class ParentClass : ISerializable
{
private ArrayList m_Collection;
public ParentClass()
{
//set up the collection of child classes
m_Collection=new ArrayList();
m_Collection.Add(new ChildClass("Hello World!"));
m_Collection.Add(new ChildClass("Hello again!"));
}
public override string ToString()
{
string s="";
foreach (ChildClass c in m_Collection)
{
s=s+c.ToString()+"\r\n";
}
return s;
}
public ParentClass(SerializationInfo info, StreamingContext context)
{
//deserialize the child collection
m_Collection=(ArrayList)info.GetValue("Collection",
typeof(ArrayList));
//loop through what has just been deserialized
Console.WriteLine("Just deserialized items:");
//THESE WILL BE BLANK BECAUSE THE CHILD CLASSES HAVEN'T BEEN
// DESERIALIZED YET
foreach (ChildClass c in m_Collection)
{
Console.WriteLine("{0}", c.ToString());
}
}
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
//serialize the collection
info.AddValue("Collection", m_Collection);
}
}
[Serializable]
class ChildClass : ISerializable
{
private string m_TestString;
public ChildClass(string testString)
{
m_TestString=testString;
}
public string TestString
{
get
{
return m_TestString;
}
}
public override string ToString()
{
return m_TestString;
}
public ChildClass(SerializationInfo info, StreamingContext context)
{
Console.WriteLine("Deserializing a child class");
m_TestString=info.GetString("v");
}
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue("v", m_TestString);
}
}
This code essentially serializes and de-serializes a parent object that contains a collection of child objects. You cannot, however, access the child objects from within the deserialization constructor of the parent object. The Have no regretsAlthough .NET provides a number of quick and easy ways to serialize and deserialize data, do not use them. A week, a month, a year, or five years down the line you will regret it.
ANTS Profiler, the simple code profiling tool from Red Gate Software, will find bottlenecks in your apps and tell you what your code is really doing.
|
||||||||||||||||||||||