Serialization of indexers

P

Pete Davis

I'm writing an XML serializer (similar to the MS XMLSerializer). It uses
reflection to get the values from a class/struct. The one area I'm confused
on is indexers. I can get the indexer PropertyInfo and the ParameterInfo
stuff, but I can't possibly know the range of valid values nor what the
underlying storage is.

How is this normally handled?

Should I just ignore the indexer and simply serialize the fields?

Pete
 
R

Richard Grimes

Pete said:
I'm writing an XML serializer (similar to the MS XMLSerializer). It
uses reflection to get the values from a class/struct. The one area
I'm confused on is indexers. I can get the indexer PropertyInfo and
the ParameterInfo stuff, but I can't possibly know the range of valid
values nor what the underlying storage is.

How is this normally handled?

Should I just ignore the indexer and simply serialize the fields?

Yes, ignore it. Take a cue from .NET serialization. It will only
serialize fields, it will not serialize properties (an indexer is a
property). This is for good reason because if a property gives access to
a field then you will serialize it elsewhere, and if it gives access to
data elsewhere (for example a database or a webservice) then that is a
different serialization issue.

Richard
 
K

Kevin Spencer

Yes, ignore it. Take a cue from .NET serialization. It will only serialize
fields, it will not serialize properties (an indexer is a property).

Actually, .Net *will* serialize properties, as long as they have a get and a
set accessor method.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.
 
P

Pete Davis

XmlSerializer serializes public properties and fields.

I've spent a couple hours going through the code in reflector, but it's just
a nightmare to understand, largely because the XmlSerializer is creating
compiling the actual serializer into a "temporary" assembly which is then
executed. What I really need, is to see the code from the temporary assembly
so I can see how it works.

BTW, I put "temporary" in quotes because the assembly is generated in the
application's appdomain, so it can't be released until the AppDomain shuts
down.

Pete
 
R

Richard Grimes

Kevin said:
Actually, .Net *will* serialize properties, as long as they have a
get and a set accessor method.

Rubbish. Read up about serialization and learn how it works.

Apart from anything else, it makes no sense for properties to be
serialized. If you have a property that is based on a field then *two*
values will be serialized and that then raises the question of which
value will be used to 'initialize' the property. If the property is used
to calculate a value at runtime (for example, reads an item from a
database) then it will be dependent upon the actual time when the data
is read and serialization of such values makes no sense.

Just to prove that you are wrong, try this:

[Serializable]
public class DataItem
{
int data;
public int Data
{
get{return data;}
set{data=value;}
}
}

Then:

SoapFormatter sf = new SoapFormatter();
DataItem dataitem = new DataItem();
dataitem.Data = 42;
using (FileStream fs = File.OpenWrite("test.soap"))
{
sf.Serialize(fs, dataitem);
}

Run this code and view the file. You'll find an entry for DataItem.data,
and not for DataItem.Data:

<DataItem>
<data>42</data>
</DataItem>

Change DataItem to:

[Serializable]
public class DataItem
{
public int Data
{
get{return 42;}
set{Console::WriteLine("dont know what to do with {0}", value);}
}
}

Run the code again. You'll find no mention of Data.

You're wrong on this one, Kevin.

Richard
 
R

Richard Grimes

Pete said:
XmlSerializer serializes public properties and fields.

Yes. But it is not .NET runtime serialization :)
I've spent a couple hours going through the code in reflector, but
it's just a nightmare to understand, largely because the
XmlSerializer is creating compiling the actual serializer into a
"temporary" assembly which is then executed. What I really need, is
to see the code from the temporary assembly so I can see how it works.

BTW, I put "temporary" in quotes because the assembly is generated in
the application's appdomain, so it can't be released until the
AppDomain shuts down.

It is actually saved to the user's temporary folder. When I tested this
out a while ago I put a FileSystemWatcher on (IIRC) %USERPROFILE%\Local
Settings\Temp and saw the generated assembly. I don't have the code at
hand but I think I implemented the event handler to copy the file to
another folder. To be honest I cannot remember whether it was
successful.

Richard
 
R

Richard Grimes

Richard said:
It is actually saved to the user's temporary folder. When I tested
this out a while ago I put a FileSystemWatcher on (IIRC)
%USERPROFILE%\Local Settings\Temp and saw the generated assembly. I
don't have the code at hand but I think I implemented the event
handler to copy the file to another folder. To be honest I cannot
remember whether it was successful.

Ah here it is, pretty rough and read, but it works:

using System;
using System.IO;

class App
{
static void Main()
{
string user = Environment.GetEnvironmentVariable("USERPROFILE");
user += @"\Local Settings\Temp";
FileSystemWatcher fsw = new FileSystemWatcher(user);
fsw.Created += new FileSystemEventHandler(newFile);
fsw.EnableRaisingEvents = true;
Console.WriteLine("press enter to finish");
Console.ReadLine();
fsw.EnableRaisingEvents = false;
fsw.Dispose();
}
// Make sure you create C:\temp
static void newFile(object o, FileSystemEventArgs args)
{
try
{
File.Copy(args.FullPath, @"C:\temp\" + args.Name);
}
catch{}
}
}

Its a bit hit and miss because the process calling XmlSerializer will
delete all the file when it has used them (I suspend the thread in the
code that calls XmlSerializer with another ReadLine so that the
XmlSerializer is not didposed before the watcher process has finished
copying file). On one run I got a .cs file, a zero length dll (obviously
it was deleted before I could completely copy it) and a .cmdline file
which was clearly the switches for the C# compiler

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top