【问题标题】:Index was outside the bounds of the array C# in unit test在单元测试中,索引超出了数组 C# 的范围
【发布时间】:2015-07-06 21:49:27
【问题描述】:

我将 QuaterDisplay 输入为虚拟数据,但出现如下错误:

索引超出了数组的范围。

代码:

private string GetQuarterDisplay(DateTime dateKey)
{
    return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
            + dateKey + "'"))[0].QuarterDisplay; //error occur here
}

internal void PropagateModelStartQuarter() 
{
    object[] args = new object[0];
    m_privateObject.Invoke("PropagateModelStartQuarter", new System.Type[0], args);
}

【问题讨论】:

  • 那么你的问题是什么,请清理你的代码,看起来它已经经历了战争
  • 它给了你这个错误,因为你试图访问你的数组中不存在的索引。如果您有 5 个索引的长度,[0], [1], [2], [3], [4] 并尝试访问 [5],那么这会给您错误 Index was outside the bounds of the array.。确保您的 AvailabilityDS.IntelTimeRow[] 数组中确实有数据
  • 什么是mAvailabilityDS.Time.Select("DateKey = '"dateKey"'"))?里面有数据吗?
  • 您可能想要使用 LINQ:return mAvailabilityDS.Time.FirstOrDefault(x => x.DateKey == dateKey)
  • Time 表中有多少行带有 DateKey,例如 12/31/2006 12:00:00 AM 4/1/2007 12:00:00 AM 7/1/2007 12:00 2007 年 9 月 30 日上午 12:00:00 2007 年 12 月 30 日上午 12:00:00 2008 年 3 月 30 日上午 12:00:00 2008 年 6 月 29 日上午 12:00:00 9/28 /2008 12:00:00 AM 12/28/2008 12:00:00 AM 3/29/2009 12:00:00 AM 3/29/2009 12:00:00 AM

标签: c# unit-testing


【解决方案1】:

我很确定这是错误的行:

((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
        + dateKey + "'"))[0]

我猜那个时间戳上没有项目,导致一个空数组。如果您尝试访问空数组中的第一项,则会出现错误。

如果你使用LINQ,你可以使用FirstOrDefault,在没有item的情况下不会失败。相反,它将返回默认值。在这种情况下null

var availability = ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
        + dateKey + "'")).FirstOrDefault();

然后:

if (availability != null)
{
    return availability.QuarterDisplay;
}
else
{
    // return a default value, or throw an exception
    return null;
}

【讨论】:

  • 我在 FirstOrDefault 收到错误,错误 2 'System.Array' 不包含 'FirstOrDefault' 的定义,并且没有扩展方法 'FirstOrDefault' 接受类型为 'System.Array' 的第一个参数被发现(您是否缺少 using 指令或程序集引用?)
  • 您应该在代码文件的顶部包含using System.Linq;
【解决方案2】:

这意味着mAvailabilityDSTime 中没有指定DateKey 字符串表示形式的行。

我会用强类型 LINQ 解决方案替换它:

private string GetQuarterDisplay(DateTime dateKey)
{
    return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select()
        .Where(x => x.DateKey == dateKey)
        .Select(x => x.QuarterDisplay)
        .FirstOrDefault();
}

编辑

主要问题是您正在通过日期/时间对象的字符串表示来搜索行,这取决于当前使用的文化。

此字符串表示与 DataTable 内部用于过滤值的标准 ISO 格式日期时间(如 2009-11-03 00:00:00)不匹配。

如果您真的想使用非强类型方法,请使用不变文化将日期/时间对象转换为字符串。

private string GetQuarterDisplay(DateTime dateKey)
{
    return ((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
            + dateKey.ToString(DateTimeFormatInfo.InvariantInfo) + "'"))[0].QuarterDisplay;
}

【讨论】:

  • Time 表中有多少行带有 DateKey,例如 12/31/2006 12:00:00 AM 4/1/2007 12:00:00 AM 7/1/2007 12:00 2007 年 9 月 30 日上午 12:00:00 2007 年 12 月 30 日上午 12:00:00 2008 年 3 月 30 日上午 12:00:00 2008 年 6 月 29 日上午 12:00:00 2007 年 9 月 28 日上午 12:00:00 /2008 12:00:00 AM 12/28/2008 12:00:00 AM 3/29/2009 12:00:00 AM 3/29/2009 12:00:00 AM
  • 那么...你的意思是什么? @无显示。您查询过这些确切时间吗?
  • 季度显示数据列:Q1 2007 Q2 2007 Q3 2007 Q4 2007 Q1 2008 Q2 2008 Q3 2008 Q4 2008 Q1 2009 Q2 2009 Q2 2009
  • 我收到错误“错误 2 'Intel.ATMSS.MetricSystem.DataObject.AvailabilityDS.IntelTimeRow[]' 不包含 'Where' 的定义并且没有扩展方法 'Where' 接受第一个参数'Intel.ATMSS.MetricSystem.DataObject.AvailabilityDS.IntelTimeRow[]' 类型的可以在 LINE (.Where(x=>x.DateKey == dateKey) )
  • 需要在文件中添加using System.Linq;指令。
【解决方案3】:

你为什么不检查null?

private string GetQuarterDisplay(DateTime dateKey)
{
    var availabilityDS = (AvailabilityDS.IntelTimeRow[])mAvailabilityDS
    if(availabilityDS != null) 
    {
        var time = availabilityDS.Time;
        if(time != null) 
        {
            var elements = availabilityDS.Select('"+ dateKey + "'");
            if(elements.Any()) 
            {
                return elements[0].QuarterDisplay;
            }
        }
    }
    return null;
}

【讨论】:

    【解决方案4】:

    您假设 Select 类返回一个项目。如果它是一个空数组,那么您正在索引一个空数组。使用类似的东西:

    private string GetQuarterDisplay(DateTime dateKey)
    {
        var times =((AvailabilityDS.IntelTimeRow[])mAvailabilityDS.Time.Select("DateKey = '"
            + dateKey + "'"));
    
        if (times.Length > 0)
        {
            return times[0].QuarterDisplay; 
        }
    
        return null; // Or whatever
    }
    

    或者使用 if (!times.Any())...

    【讨论】:

      【解决方案5】:

      DataTable.Select 没有返回任何行,因此如果您尝试访问不存在的行,则会收到上述异常。

      您可能希望使用 LINQ 来代替它,这使其更具可读性:

      var timeRow = mAvailabilityDS.Time.FirstOrDefault(x => x.DateKey == dateKey);
      if(timeRow != null)
          return timeRow.QuarterDisplay;
      else
          return null;
      

      也许您没有找到任何行,因为您想忽略某个时间部分。然后可以使用DateTimeDate属性:

      var timeRow = mAvailabilityDS.Time.FirstOrDefault(x => x.DateKey.Date == dateKey.Date);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-06
        • 2010-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 2021-01-23
        相关资源
        最近更新 更多