Исключение индекса вне допустимого диапазона в c #

Я использую silverlight и выполняю сериализацию с использованием кода C #. У меня есть класс parameters и внутри него есть списки parameter и separator:

[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>();
    }

И снова внутри класса Parameter у меня есть:

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

А также:

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

и так далее.

Теперь я использую XmlWriter ниже в основной функции:

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();
           }  
}

Я получаю сообщение об ошибке Index was out of range. It must not be negative and must be less than the size of the collection. в строке prs[0].Parameter[0].Name = "shek1";. Я знаю, что проблема в классе параметров. У меня есть класс Parameter, и он работает, если я присваиваю какое-либо значение полю класса Parameters, но когда я перехожу к классу Parameter, он имеет ошибку индекса вне диапазона.

Как мне решить эту проблему?


person Sss    schedule 25.06.2014    source источник


Ответы (2)


Индексируйте его вне допустимого диапазона, потому что у вас пустой массив. И вы не можете получить доступ к элементу из пустого массива, потому что в нем нет элементов.

Здесь вы создаете свой массив из Parameters объектов:

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

На данный момент у вас есть 4-элементный массив Parameterses, 3 из которых имеют допустимый объект Parameters (4-й по какой-то причине оставлен пустым). Теперь у каждого объекта Parameters есть свойство Parameter (которое, кстати, действительно сбивает с толку, я рекомендую лучше именовать типы / переменные):

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

Итак, свойство Parameter - это new List<Parameter>(), то есть пустой список. Затем вы пытаетесь получить доступ к элементу из пустого списка:

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

prs[0] - это Parameter объект, а .Parameter - пустой List<Parameter>. У него нет элемента с индексом 0. Отсюда и ошибка.

Если вам нужно инициализировать List<Parameter> в вашем Parameter объекте, вы можете сделать это в этом объекте так же, как при создании массива Parameters. Или вы можете просто добавить его там, где вы его используете:

prs[0].Parameter.Add(new Parameter());
prs[0].Parameter[0].Name = "shek1";
person David    schedule 25.06.2014
comment
Даже если я сделаю это Parameters [] prs = new Parameters [3]; он по-прежнему делает то же самое. - person Sss; 25.06.2014
comment
@ user234839: Я ожидал этого, потому что это не было причиной проблемы. Проблема вызвана тем, что каждый объект Parameters имеет пустой список в качестве свойства Parameter, и вы не можете ссылаться на элемент из пустого списка. (И я подозреваю, что это вызвано действительно неинтуитивным именованием, которое вы используете для этих параметров, что затрудняет даже описание проблемы.) - person David; 25.06.2014

Это связано с тем, что когда вы вызываете prs[0].Parameter[0].Name = "shek1";, свойство Parameter является пустым списком (private readonly List<Parameter> b1 = new List<Parameter>();), поэтому это список, но содержит ноль элементов.

Вам нужно сначала добавить элемент, а затем присвоить имя следующим образом:

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

Или сокращенно до этого:

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

Вам нужно повторить это с другими вызовами, например с prs[1], prs[2] и т. Д., Но, надеюсь, вы поняли идею.

person Belogix    schedule 25.06.2014
comment
Хорошо, позвольте мне реализовать, отметим вас, как только это заработает. - person Sss; 25.06.2014