Serialization is really a powerful feature. My personal favorite is the binary kind, but it has a limit. If you try to deserialize an object who's class has changed since it was serialized chances are that you will most likely get an exception. I have tried it on several occasions, but I never got around to research the problem, before now.
There are three possible solutions to the problem as far as I see it, all of them having one thing in common: they all require that the classes that are to be serialized implements ISerializable.
It does not take that much effort to implement ISerializable. There are only one method in the interface that the compiler requires you to implement which is GetObjectData but you will also have to implement the constructor that is used for deserialization. Since interfaces cannot contain constructors you will have to remember this yourself, or you will be gently hinted at runtime when trying to deserialize an object that does not have that constructor.
Now the trick is that inside the constructor you must implement a check that makes sure that the values that must be deserialized exists in the SerializationInfo object. I call it a trick because I am not able to find a beautiful way of checking if the values are available. Currently I see three not that beautiful ways to do that check:
1) try and catch
You surround each of the value readings with a try/catch. So in case that the value is not available you catch the exception and set a default value.
2) Assembly name
You read the AssemblyName property from the SerializationInfo object. This string contains the Version of the assembly when the object was serialized. If you remember to update this version number when compiling your assemblies you can use it to evaluate how to proceed reading the values.
3) Reflection
The SerializationInfo class has a private (surprised?) method named FindElement which returns the index of the element if it exists and -1 if the element does not exist. I know you really cannot use the index for anything but the -1 is the one you would want to check for. If the method return -1 you know that it will do no good to try to get the value.
Now that wasn't so bad, but hopefully in the future we will get a public method that can tell us if the element exists in the SerializationInfo object.
$0.02
Read more!
Friday, January 25, 2008
Binary Serialization and versioning
Posted by
Robin Theilade
at
21:41
0
comments
Links to this post
Labels: .net, c#, iserializable, serialization
Sunday, December 16, 2007
Member prefixs in cref attributes for xml documentation
Besides the not so meaningful description, the contents of this blog is actually pretty simple for an experienced .NET developer.
This post is simple about the prefixes of reference IDs used when writing XML documentation. Here is an example of what I'm talking about.
<see cref="E:System.Timers.Timer.Elapsed" />
The tag above means that the documentation should contain a link to the event (prefix: E) Elapsed on the type System.Timers.Timer.
So which prefixes actually exists? For some reason I never get the correct link first time when Googling so here is a quick list.
| N | Namespace |
| T | Type (class, struct, enum, delegate, interface) |
| D | Typedef |
| F | Field |
| P | Property |
| M | Method |
| E | Event |
For further information about the subject visit this page.
Read more!
Posted by
Robin Theilade
at
22:13
1 comments
Links to this post
Tuesday, October 23, 2007
How easy it is to destroy the internet experience for everybody else
At some point we have all been exposed to ads when we search the Internet. Some may have installed ad-removal software to get rid of the ads and some haven't. But the fact is that even if you have ad-blocking software installed you cannot completely avoid the ads on the Internet.
Ads serves two purposes for the visitors point of view (laugh now, but at least I tried to come up with an excuse for the existence of ads):
1) Keeps websites running for free or sometimes for a small fee
2) Makes it possible for websites to have better content or bandwidth
So even though we hate ads more than anything else, they do serve some kind of purpose.
Whats worse is ads that tries to trick you into buying crap. Personally I've been seeing an ad for the same company for quite a while now. It tries to trick you into buying the company's anti-virus software and now also their anti-malware software.
The ad is very annoying because it redirects away from the page you were visiting to their fake warning site, where they want you to download their software (I don't even know if it's actually a real piece of software or if it is just another malware).
The first thing you will see is their message box:
you can't do anything else than clicking the OK button and when you do that you will get redirected to their fake warning site:
On this page every link you try to click links to their installer which they want you to download. It doesn't take much of a programmer to see in the binary that the installer will download a load of crap from their site and tweak your Windows settings to make it look like there really is something wrong with you machine (actually when first you have run this installer they are probably right about that you have a problem with you Windows, but they are to blame).
So the lesson here is:
DO NOT ACCEPT OR DOWNLOAD ANYTHING FROM THEM!
By the way, if you know the people behind these ads please do me a favor and tie their shoelaces together at least once a month for wasting my time.
Read more!
Posted by
Robin Theilade
at
21:05
0
comments
Links to this post
Saturday, October 20, 2007
Invoking a method that takes a pointer as an argument
I'm currently playing around with a cloned StringBuilder. This builder needs to call some methods on the String class which is internal, so reflection is the only way to call them. Usually that's no problem, but this time some of the methods accepted Char* as arguments and I haven't dealt with that before in reflection matters.
Getting the method info
The method I'm interested in is:
If there were no overloads this would be pretty easy since then I wouldn't have to supply the Type.GetMethod method with an array of argument types for the method. But this method has 5 overloads, so I need to be specific to the GetMethod method. The problem is that I have not tried to get a type of a pointer before so I didn't know what to write.
By calling the Type.GetMethods method I get a list of all the methods that the String class has. In that list I find the specific overload of AppendInPlace and by examining the MethodInfo that is returned I can see what the type is called. It was actually pretty simple: System.Char*
Knowing that I can now create the array of types and get the correct MethodInfo instance:
Type type = typeof( String );
BindingFlags internalInstance = BindingFlags.NonPublic | BindingFlags.Instance;
Type[] types = GetTypeArray( Type.GetType( "System.Char*" ), count.GetType(), currentLength.GetType() );
MethodInfo info = type.GetMethod( "AppendInPlace", internalInstance, null, types, null );
Invoking the method
Now everything is good to go, we have the MethodInfo, the arguments and the object to invoke the method on, what can possibly go wrong? Oh yeah, you cannot pass a Char* to a method that takes an array of objects as MethodInfo.Invoke does. But luckily the solution was quite easy. You just have to create an instance of IntPtr using the Char* in the constructor, like this:
Object[] objects = GetObjectArray( new IntPtr( value ), count, currentLength );
info.Invoke( str, objects );
That's all there is to it.
Read more!
Posted by
Robin Theilade
at
22:09
0
comments
Links to this post
Labels: .net, pointers, programming, reflection, string, stringbuilder
Thursday, October 18, 2007
A nice SVN (Subversion) feature
Generally I like to use SVN as my source repository. I have several reasons for this, but the main reason is that you're not only getting a tool that works, you're also getting small surprises once i while. I got this one today:

What happened here was that I was renaming NewDefault.aspx to Default.aspx and then TortoiseSVN detected that maybe I would like to rename the C# file as well.
If you are a .NET programmer you're probably sitting right now saying to yourself that Visual Studio does this for you, but I'm not renaming from within Visual Studio, I'm actually renaming the files in the Windows Explorer, thanks to TortoiseSVN.
Don't miss out on the SVN fun:
SVN (client)
TortoiseSVN (Windows Shell extension)
AnkhSVN (Visual Studio addin)
SVNRepository.com (Hosted SVN - Great service!!)
Read more!
Posted by
Robin Theilade
at
19:12
0
comments
Links to this post
Labels: subversion, svn, tortoisesvn
Sunday, October 7, 2007
The balcony with no access

Often when you put in a balcony you also put in some kind of way to access the balcony. This picture was taken not far from where I live.
Read more!
Posted by
Robin Theilade
at
22:08
1 comments
Links to this post
Wednesday, October 3, 2007
Multi row delete in DataGridView
There are three events on the DataGridView which is directly related to row deletion: "RowsRemoved", "UserDeletedRow" and "UserDeletingRow". Entertaining enough all of them are called once for each row that is to be deleted.
Sadly I did not have a solution at hand and I kept wondering how to solve that problem. Today I sat down and tried to solve the problem.
I quickly found that adding a KeyDown event handler and then monitor the Delete key could do the trick. All I had to do was to ask the user and set "e.Handled" to true if I did not want to delete the rows.
private void fruitsDataGridView_KeyDown( object sender, KeyEventArgs e )
{Int32 count = this.fruitsDataGridView.SelectedRows.Count;
if( count.Equals( 0 ) ) { return;}
e.Handled = !this.ConfirmDeletion( count );}
However, simple as it was I did not like the solution. So I started looking at the Call Stack to see which methods would help raising the three events that is raised once per row. A couple of lines down the Call Stack I found a method named "ProcessDeleteKey", nice! This method was for once not marked private or internal, but someone "forgot" to add the virtual keyword to the method's signature, so I were not able to override it. So I looked at the method that called the "ProcessDeleteKey". It is named "ProcessDataGridViewKey" and is both protected and virtual. So I quickly made a new class inheriting from DataGridView and made an overridden "ProcessDataGridViewKey" method where I could check for the Delete key and take action if needed. Additionally I added a new event to the class named UserDeletingRows that would be called once per deletion batch.
protected virtual Boolean ProcessDeleteKey( KeyEventArgs e )
{if( !this.AllowUserToDeleteRows )
{return false;
}
if( this.EditingControl != null )
{return false;
}
CancelEventArgs args = new CancelEventArgs( false );
this.OnUserDeletingRows( args ); if( args.Cancel ) {return true;
}
return base.ProcessDeleteKey( e.KeyData );
}
The Solution
Although the first solution is simpler, I find that the second solution is much better, because having the implementation within the grid class should make it be used more often. If only I can find a better name for the new event.
Both solutions are included in the downloadable project.
Solution: Visual Studio 2005
Language: C#
Framework: 2.0
Read more!
Posted by
Robin Theilade
at
21:22
1 comments
Links to this post
Labels: .net, 2.0, c#, datagridview, events, programming, system.windows.forms

