0

I'm using silverlight and doing serialisation using c# code. I have a parameters class and inside it I have parameter and separator lists:

[XmlRoot(ElementName = "parameters")]
    public class Parameters
    {       
       [XmlElement("separator")]
       public List<Separator> Separator { get { return a1; } }
       private readonly List<Separator> a1 = new List<Separator>(); 

       [XmlElement("parameter")]
       public List<Parameter> Parameter { get { return b1; } }
       private readonly List<Parameter> b1 = new List<Parameter>();
    }

And again inside the Parameter class I have:

[XmlElement("name")]
        public string Name { get; set; }

And also:

[XmlElement("component")]
        public List<Component> Component { get { return b3; } }
        private readonly List<Component> b3 = new List<Component>();

and so on.

Now I'm using XmlWriter below in the main function:

public void Main()
{
           Parameters[] prs = new Parameters[4];
           prs[0] = new Parameters();
           prs[1] = new Parameters();
           prs[2] = new Parameters(); 

           prs[0].Parameter[0].Name = "shek1";
           prs[0].Parameter[0].Component[0].Type = "type1";

           prs[1].Separator[0].Separators = "sep1";

           prs[2].Parameter[0].Name = "shek2";
           prs[2].Parameter[0].Component[0].Type = "type2";

StringBuilder output = new StringBuilder();
            XmlWriterSettings ws = new XmlWriterSettings();
            ws.Indent = true;
            using (XmlWriter writer = XmlWriter.Create(output, ws))
           {
               writer.WriteStartDocument();
               writer.WriteStartElement("Parameters");
               int count = 0;
              foreach (var param in prs)
               {
                   writer.WriteStartElement("Parameter");
                   writer.WriteElementString("Name", param.Parameter[count].Name);
                   writer.WriteStartElement("Component");
                   writer.WriteElementString("Type", param.Parameter[count].Component[0].Type);
                   writer.WriteStartElement("Attribute");
                   writer.WriteElementString("Items", param.Parameter[count].Component[0].Attributes[0].Items[count]);
                   writer.WriteEndElement(); 
              }
              writer.WriteEndElement();
              writer.WriteEndDocument();
           }  
}

The error I'm getting is Index was out of range. It must not be negative and must be less than the size of the collection. in line prs[0].Parameter[0].Name = "shek1";. I know the problem is inside the Parameters class. I have the Parameter class and it is working if I assign any value to the field of Parameters class, but when I go to the Parameter class then it has this index out of range error.

How do I solve this problem?

Alium Britt
  • 1,246
  • 4
  • 13
  • 25
Sss
  • 1,519
  • 8
  • 37
  • 67

2 Answers2

3

The index it out of range because you have an empty array. And you can't access an element from an empty array because it has no elements.

Here you create your array of Parameters objects:

Parameters[] prs = new Parameters[4];
prs[0] = new Parameters();
prs[1] = new Parameters();
prs[2] = new Parameters(); 

At this point you have a 4-element array of Parameterses, 3 of which have a valid Parameters object (the 4th is left empty for some reason). Now each Parameters object has a Parameter property (which, by the way, is getting really confusing, I recommend better type/variable naming):

public List<Parameter> Parameter { get { return b1; } }
private readonly List<Parameter> b1 = new List<Parameter>();

So the Parameter property is a new List<Parameter>(), which is an empty list. Then you try to access an element from the empty list:

prs[0].Parameter[0].Name = "shek1";

prs[0] is a Parameter object, but .Parameter is an empty List<Parameter>. It has no element at index 0. Hence the error.

If you need to initialize the List<Parameter> in your Parameter object then you can do so in that object just as you do when you create your array of Parameters. Or you can just add one in place where yo use it:

prs[0].Parameter.Add(new Parameter());
prs[0].Parameter[0].Name = "shek1";
David
  • 208,112
  • 36
  • 198
  • 279
  • Even if i do this Parameters[] prs = new Parameters[3]; it stil do same. – Sss Jun 25 '14 at 12:22
  • 2
    @user234839: I would expect so, since that wasn't causing the problem. The problem is caused by the fact that each `Parameters` object has an empty list as a `Parameter` property, and you can't reference an element from an empty list. (And I would suspect is caused by the *really* unintuitive naming you're using for these "parameters" which makes it difficult to even *describe* the problem.) – David Jun 25 '14 at 12:23
1

This is because when you call prs[0].Parameter[0].Name = "shek1"; the Parameter property is an empty list (private readonly List<Parameter> b1 = new List<Parameter>();) so is a list but contains zero elements.

You need to add an element first and then assign the name like this:

prs[0].Parameter.Add(new Parameter());
prs[0].Parameter[0].Name = "shek1";
prs[0].Parameter[0].Component[0].Type = "type1";

Or condensed down to this:

prs[0].Parameter.Add(new Parameter
    { 
        Name = "shek1",
        Type = "type1"
    });

You need to repeat this with other calls, so to prs[1] and prs[2] etc but hopefully you get the idea.

Belogix
  • 8,129
  • 1
  • 27
  • 32