【问题标题】:"Index was out of range" exception in c# [duplicate]c#中的“索引超出范围”异常[重复]
【发布时间】:2014-06-25 12:10:39
【问题描述】:

我正在使用 silverlight 并使用 c# 代码进行序列化。 我有一个parameters 类,里面有parameterseparator 列表:

[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 类时,它的索引超出范围错误。

我该如何解决这个问题?

【问题讨论】:

    标签: c# .net xml xml-serialization xmlwriter


    【解决方案1】:

    索引超出范围,因为您有一个空数组。而且你不能从一个空数组中访问一个元素,因为它没有元素。

    在这里,您可以创建 Parameters 对象数组:

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

    此时,您有一个由 Parameterses 组成的 4 元素数组,其中 3 个具有有效的 Parameters 对象(由于某种原因,第 4 个为空)。现在每个Parameters 对象都有一个Parameter 属性(顺便说一句,这真的很混乱,我建议更好的类型/变量命名):

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

    所以Parameter 属性是new List&lt;Parameter&gt;(),它是一个空列表。然后你尝试从空列表中访问一个元素:

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

    prs[0] 是一个 Parameter 对象,但 .Parameter 是一个空的 List&lt;Parameter&gt;。它在索引0 处没有元素。因此出现错误。

    如果您需要在Parameter 对象中初始化List&lt;Parameter&gt;,那么您可以在该对象中执行此操作,就像您在创建Parameters 数组时所做的那样。或者你可以在你使用它的地方添加一个:

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

    【讨论】:

    • 即使我这样做 Parameters[] prs = new Parameters[3];它仍然做同样的事情。
    • @user234839:我希望如此,因为这不会导致问题。问题是由于每个Parameters 对象都有一个空列表作为Parameter 属性,并且您不能从空列表中引用元素。 (我怀疑是由于您对这些“参数”使用的真的不直观的命名,这使得甚至难以描述问题。)
    【解决方案2】:

    这是因为当您调用 prs[0].Parameter[0].Name = "shek1"; 时,Parameter 属性是一个空列表 (private readonly List&lt;Parameter&gt; b1 = new List&lt;Parameter&gt;();),因此也是一个包含零个元素的列表。

    您需要先添加一个元素,然后像这样分配名称:

    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] 等,但希望您能理解。

    【讨论】:

    • 好吧,让我实现它会尽快标记你。
    猜你喜欢
    • 2012-02-09
    • 2014-07-21
    • 2021-10-25
    • 1970-01-01
    • 2014-07-23
    • 2016-05-03
    • 2015-02-11
    • 1970-01-01
    相关资源
    最近更新 更多