Xml Serialization

C

coder316

Hello,
I have this class(Someone elses code):
public class SerializableDictionary<TKey, TValue>

: Dictionary<TKey, TValue>, IXmlSerializable

....................

The class creates an object that resembles a Generic Dictionary and
now I want to convert it to one (Generic Dictionary) Do I have to loop
through the keys and values and add them to mine? Or is there an
easier way?
Thanks
 
J

Jesse Houwing

* coder316 wrote, On 19-1-2010 18:14:
Hello,
I have this class(Someone elses code):
public class SerializableDictionary<TKey, TValue>

: Dictionary<TKey, TValue>, IXmlSerializable

...................

The class creates an object that resembles a Generic Dictionary and
now I want to convert it to one (Generic Dictionary) Do I have to loop
through the keys and values and add them to mine? Or is there an
easier way?
Thanks

In essence it still is a generic dicionary. But why would you want to
make a real generic dictionary from this stongly typed collection? what
does that give you what this doesn't?

If you really need a 'normal' generic reference, just assign this
collection to it like so:

class Program
{
static void Main(string[] args)
{
SpecializedDictionary dict = new SpecializedDictionary();
Dictionary<string, int> genericDict = dict;
}

public class SpecializedDictionary : Dictionary<string, int>
{

}
}

Due to inheritance it just *is* a generic collection, but then one with
a fancy name and with XML serialization support.
 
A

AMP

* coder316 wrote, On 19-1-2010 18:14:
Hello,
I have this class(Someone elses code):
public class SerializableDictionary<TKey, TValue>
     : Dictionary<TKey, TValue>, IXmlSerializable

The class creates an object that resembles a Generic Dictionary and
now I want to convert it to one (Generic Dictionary) Do I have to loop
through the keys and values and add them to mine? Or is there an
easier way?
Thanks

In essence it still is a generic dicionary. But why would you want to
make a real generic dictionary from this stongly typed collection? what
does that give you what this doesn't?

If you really need a 'normal' generic reference, just assign this
collection to it like so:

     class Program
     {
         static void Main(string[] args)
         {
             SpecializedDictionary dict = new SpecializedDictionary();
             Dictionary<string, int> genericDict = dict;
         }

         public class SpecializedDictionary : Dictionary<string, int>
         {

         }
     }

Due to inheritance it just *is* a generic collection, but then one with
a fancy name and with XML serialization support.

I am having a problem accessing the inherited methods.
I have tried using Add and CopyTo and both give me a converting error,
but my dictionary has he same signature as the one the class has:
........SerializableDictionary<int, string[]> sd2 = new
SerializableDictionary<int, string[]>();


Dictionary<int, string[]> Picks = new Dictionary<int, string[]>();
this.Add(key, value); this works
Picks.Add(key,value); this doesnt

Also while I have your ear....
I havent seen an explanation of these brackets anywhere in the
documentation

XClass<x,y>
Thanks
 
A

AMP

* coder316 wrote, On 19-1-2010 18:14:
In essence it still is a generic dicionary. But why would you want to
make a real generic dictionary from this stongly typed collection? what
does that give you what this doesn't?
If you really need a 'normal' generic reference, just assign this
collection to it like so:
     class Program
     {
         static void Main(string[] args)
         {
             SpecializedDictionary dict = new SpecializedDictionary();
             Dictionary<string, int> genericDict = dict;
         }
         public class SpecializedDictionary : Dictionary<string, int>
         {
         }
     }
Due to inheritance it just *is* a generic collection, but then one with
a fancy name and with XML serialization support.

I am having a problem accessing the inherited methods.
I have tried using Add and CopyTo and both give me a converting error,
but my dictionary has he same signature as the one the class has:
            ........SerializableDictionary<int, string[]> sd2= new
SerializableDictionary<int, string[]>();

Dictionary<int, string[]> Picks = new Dictionary<int, string[]>();
            this.Add(key, value); this works
           Picks.Add(key,value); this doesnt

Also while I have your ear....
 I havent seen an explanation of these brackets anywhere in the
documentation

XClass<x,y>
Thanks- Hide quoted text -

- Show quoted text -

I get these errors on most attempts to do anything:
cannot convert from 'TKey' to 'int'
cannot convert from 'TValue' to 'string[]'
 
P

Peter Duniho

AMP said:
I am having a problem accessing the inherited methods.
I have tried using Add and CopyTo and both give me a converting error,
but my dictionary has he same signature as the one the class has:
........SerializableDictionary<int, string[]> sd2 = new
SerializableDictionary<int, string[]>();


Dictionary<int, string[]> Picks = new Dictionary<int, string[]>();
this.Add(key, value); this works
Picks.Add(key,value); this doesnt

Without a complete code example, there's no way to explain an error. At
the very least, you need to show _all_ declarations of _all_ variables,
methods, types, etc. in your code that are not part of the .NET
Framework itself.

The code you posted above has no obvious reason why the compiler would
emit the error you describe in the follow-up post.
Also while I have your ear....
I havent seen an explanation of these brackets anywhere in the
documentation

XClass<x,y>

http://msdn.microsoft.com/en-us/library/512aeb7t.aspx

Pete
 
A

AMP

AMP said:
I am having a problem accessing the inherited methods.
I have tried using Add and CopyTo and both give me a converting error,
but my dictionary has he same signature as the one the class has:
            ........SerializableDictionary<int, string[]> sd2 = new
SerializableDictionary<int, string[]>();
Dictionary<int, string[]> Picks = new Dictionary<int, string[]>();
            this.Add(key, value); this works
           Picks.Add(key,value); this doesnt

Without a complete code example, there's no way to explain an error.  At
the very least, you need to show _all_ declarations of _all_ variables,
methods, types, etc. in your code that are not part of the .NET
Framework itself.

The code you posted above has no obvious reason why the compiler would
emit the error you describe in the follow-up post.
Also while I have your ear....
 I havent seen an explanation of these brackets anywhere in the
documentation
XClass<x,y>

http://msdn.microsoft.com/en-us/library/512aeb7t.aspx

Pete

Peter:
Here is the class I am trying to use. I am able to create the xml file
with an xml writer and deserialize it.When I deserialze it "this" gets
populated like a dictionary, in fact thats what I think it is, but I
cant seam to use the aformentioned Dictionary methods. I know I'm
looking at it wrong, but I'm not sure why.
using System;

using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;


[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>

: Dictionary<TKey, TValue>, IXmlSerializable
{

#region IXmlSerializable Members

public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}


public SerializableDictionary()

: base()
{

}

public SerializableDictionary(IDictionary<TKey, TValue>
dictionary)

: base(dictionary)
{

}

public SerializableDictionary(IEqualityComparer<TKey> comparer)

: base(comparer)
{

}

public SerializableDictionary(int capacity)

: base(capacity)
{

}

public SerializableDictionary(IDictionary<TKey, TValue>
dictionary, IEqualityComparer<TKey> comparer)

: base(dictionary, comparer)
{

}

public SerializableDictionary(int capacity,
IEqualityComparer<TKey> comparer)

: base(capacity, comparer)
{

}



public void ReadXml(System.Xml.XmlReader reader)
{
string[] foos = new string[this.Count]; //for test purposes

Dictionary<int, string[]> Picks = new Dictionary<int, string[]>
(); //for test purposes
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

XmlSerializer valueSerializer = new XmlSerializer(typeof
(TValue));

bool wasEmpty = reader.IsEmptyElement;

reader.Read();

if (wasEmpty)

return;

while (reader.NodeType != System.Xml.XmlNodeType.EndElement
&& !reader.EOF)
{

reader.ReadStartElement("item");

reader.ReadStartElement("key");

TKey key = (TKey)keySerializer.Deserialize(reader);

reader.ReadEndElement();

reader.ReadStartElement("value");

TValue value = (TValue)valueSerializer.Deserialize
(reader);

reader.ReadEndElement();

this.Add(key, value); //works
//Picks.Add(key,value); //Not working
// this.Values.CopyTo(foos,0); //Not working

reader.ReadEndElement();
reader.MoveToContent();

}

if (!reader.EOF)

reader.ReadEndElement();

}




public void WriteXml(System.Xml.XmlWriter writer)
{

XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

XmlSerializer valueSerializer = new XmlSerializer(typeof
(TValue));



foreach (TKey key in this.Keys)
{

writer.WriteStartElement("item");



writer.WriteStartElement("key");

keySerializer.Serialize(writer, key);

writer.WriteEndElement();



writer.WriteStartElement("value");

TValue value = this[key];

valueSerializer.Serialize(writer, value);

writer.WriteEndElement();
writer.WriteEndElement();

string xml = writer.ToString();
//return xml = writer.ToString();
}
writer.Flush();
writer.Close();
}

#endregion

}
 
P

Peter Duniho

AMP said:
Here is the class I am trying to use. I am able to create the xml file
with an xml writer and deserialize it.When I deserialze it "this" gets
populated like a dictionary, in fact thats what I think it is, but I
cant seam to use the aformentioned Dictionary methods. I know I'm
looking at it wrong, but I'm not sure why.

Unfortunately, you still have not posted a complete code example.
However, there's enough in the code you did post to know what the
specific problem is: you have declared the "SerializableDictionary"
class as a generic type, but you are attempting to use a specific,
concrete version of the generic "Dictionary" class in your "for test
purposes" code.

So, when you compile "SerializableDictionary<TKey, TValue>", the type
parameters are just that: type parameters. They are not yet actual
types. But of course the "Picks" variable uses specific type arguments,
int and string[]. There being no valid conversion from the
unconstrained generic type arguments TKey and TValue to the specific
types int and string[], you get a compiler error.

Frankly, it's not at all clear why you are even doing what you're trying
to do with that code. What "test purposes" are served with that local
variable? Given that the code you are showing should, without the
"Picks" variable at all, work just fine, what's the point?

If you really want to include some kind of test code, you will need to
make that part of the code generic as well. For example, changing the
declared type of "Picks" from "Dictionary<int, string[]>" to
"Dictionary<TKey, TValue>" would allow the call to "Picks.Add()" to
work. Likewise, if you had declared "foos" as "TValue[]", the following
statement calling "this.Values.CopyTo()" should work as well.

On that second statement, note that even if your SerializableDictionary
were not generic, and simply inherited Dictionary<int, string[]>, the
declaration for "foos" would not have been valid. As the "Values"
property is a collection of the value type, and the value type is itself
an array string[], the type of the destination array for the call to
"CopyTo()" has to be "string[][]", not "string[]".

Additionally, you initialize that array to be the length of the
dictionary on entering the "ReadXml()" method, but of course at that
point the length is 0. Why you're trying to copy all the values from
the dictionary to an array each time through the loop, I don't know.
But for that to work, you need to make sure that the destination array
"foos" is large enough to contain all the values _currently_ in the
dictionary when you make the call. The simplest approach being to
simply reallocate the array each time through the loop; of course,
that's inefficient, so you could instead use some kind of
doubling-in-size approach. In any case, the destination array must be
large enough to contain all the values from the Values property
collection, or else an exception will be thrown when you call CopyTo().

Pete
 
A

AMP

AMP said:
Here is the class I am trying to use. I am able to create the xml file
with an xml writer and deserialize it.When I deserialze it "this" gets
populated like a dictionary, in fact thats what I think it is, but I
cant seam to use the aformentioned Dictionary methods. I know I'm
looking at it wrong, but I'm not sure why.

Unfortunately, you still have not posted a complete code example.
However, there's enough in the code you did post to know what the
specific problem is: you have declared the "SerializableDictionary"
class as a generic type, but you are attempting to use a specific,
concrete version of the generic "Dictionary" class in your "for test
purposes" code.

So, when you compile "SerializableDictionary<TKey, TValue>", the type
parameters are just that: type parameters.  They are not yet actual
types.  But of course the "Picks" variable uses specific type arguments,
int and string[].  There being no valid conversion from the
unconstrained generic type arguments TKey and TValue to the specific
types int and string[], you get a compiler error.

Frankly, it's not at all clear why you are even doing what you're trying
to do with that code.  What "test purposes" are served with that local
variable?  Given that the code you are showing should, without the
"Picks" variable at all, work just fine, what's the point?

If you really want to include some kind of test code, you will need to
make that part of the code generic as well.  For example, changing the
declared type of "Picks" from "Dictionary<int, string[]>" to
"Dictionary<TKey, TValue>" would allow the call to "Picks.Add()" to
work.  Likewise, if you had declared "foos" as "TValue[]", the following
statement calling "this.Values.CopyTo()" should work as well.

On that second statement, note that even if your SerializableDictionary
were not generic, and simply inherited Dictionary<int, string[]>, the
declaration for "foos" would not have been valid.  As the "Values"
property is a collection of the value type, and the value type is itself
an array string[], the type of the destination array for the call to
"CopyTo()" has to be "string[][]", not "string[]".

Additionally, you initialize that array to be the length of the
dictionary on entering the "ReadXml()" method, but of course at that
point the length is 0.  Why you're trying to copy all the values from
the dictionary to an array each time through the loop, I don't know.
But for that to work, you need to make sure that the destination array
"foos" is large enough to contain all the values _currently_ in the
dictionary when you make the call.  The simplest approach being to
simply reallocate the array each time through the loop; of course,
that's inefficient, so you could instead use some kind of
doubling-in-size approach.  In any case, the destination array must be
large enough to contain all the values from the Values property
collection, or else an exception will be thrown when you call CopyTo().

Pete

Thats why you are priceless. As soon as I was done reading, I knew
what was wrong. A minute later all the code fell into place.
As Always, THANKS!!
 
P

Peter Duniho

AMP said:
Thats why you are priceless. As soon as I was done reading, I knew
what was wrong. A minute later all the code fell into place.
As Always, THANKS!!

Glad I could help. Frankly, I'm relieved; I was worried when I wrote
all that, that there was too much information all in one place and that
I hadn't presented it very carefully.

I'm happy you were able to get your code working.

Pete
 

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