【问题标题】:Check if IEnumerable<object> has any values inside without getting IndexOutOfRangeException检查 IEnumerable<object> 内部是否有任何值而不获取 IndexOutOfRangeException
【发布时间】:2021-04-07 20:49:30
【问题描述】:

我有一个IEnumerable&lt;object&gt;。我想检查IEnumerable&lt;object&gt; 里面是否有任何值。

我的方法是这样的:

private static JObject TransformExcelDatasource(Stream originalDatasource)
{
            // Read Excel Data
            var excelReader = new ExcelReader(originalDatasource);
            var sheetReader = excelReader[0];

            //Check if row has any values
            var row = sheetReader.Row(100);
            var rowHasValues = row.Any();
            if (rowHasValues)
            {
                //do stuff
            }
}

我尝试获取只有 3 行的 Excel 表的第 100 行。我知道,这只是一个 POC。

var rowHasValues = row.Any(); 行抛出 System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

这就是变量IEnumerable&lt;object&gt;row 的样子:

我尝试了这些问题的答案(firstsecond),但对我没有任何帮助。

我如何检查IEnumerable&lt;object&gt; row 是否有任何值而不得到IndexOutOfRangeException?

更新

这是抛出的 IndexOutOfRangeException

row.Current 也不是一个选项,因为它 IEnumerable&lt;object&gt; 不包含它。

完整的堆栈跟踪:

   at LightWeightExcelReader.SheetReader.get_Item(String cellAddress)
   at LightWeightExcelReader.SheetReader.<get_Item>b__8_1(String x)
   at System.Linq.Utilities.<>c__DisplayClass2_0`3.<CombineSelectors>b__0(TSource x)
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
   at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformExcelDatasource(Stream originalDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 35
   at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformDatasource(IDatasource interpretedDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 19
   at NR.DataAdapter.Core.DataAdapter.AdaptDatasources() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\DataAdapter.cs:line 24
   at NR.DataAdapter.UI.Controllers.HomeController.Dashboard() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.UI\Controllers\HomeController.cs:line 24
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

【问题讨论】:

  • 值得注意的是(从您的图片中)该行是一个 SelectListIterator。我真的很惊讶row.Any() 抛出。但是(也来自你的图片),你可以试试row.Current != null
  • 再看你的照片。你确定row.Any()在扔吗?如果不展开调试助手中的Results View,会不会出现异常?
  • @Flydog57 我会用你的问题的答案更新问题
  • @Nightscape 请edit您的问题包括异常的完整堆栈跟踪。
  • 您也可以尝试将row 的声明从IEnumerable&lt;object&gt; 更改为var。通过强制变量的类型(到接口而不是实际类型),您最终可能会调用 Any 的错误实现

标签: c# ienumerable indexoutofrangeexception


【解决方案1】:

我相信您可以在尝试访问 Row 索引之前检查 MaxRow 属性。

private static JObject TransformExcelDatasource(Stream originalDatasource)
{
    // Read Excel Data
    var excelReader = new ExcelReader(originalDatasource);
    var sheetReader = excelReader[0];

    // Check if the row is not out of limits.
    if (sheetReader.MaxRow < 100) return null;

    // Check if row has any values
    var row = sheetReader.Row(100);
    var rowHasValues = row.Any();
    if (rowHasValues)
    {
        //do stuff
    }
}

【讨论】:

  • 谢谢,你解决了我的问题,但问题仍然存在,为什么 .Any() 会抛出 IndexOutOfRangeException。就像 cmets 中提到的一些人一样,它是我正在使用的框架中的一个错误是安全的。我将在存储库中创建一个问题
  • 我看了一下代码。我看到“Row(100)”方法只返回 Linq 查询“CellRef.Range(topLeft, bottomRight).Select(x => x.ToString()).Select(x => this[x])”。这个 Linq 查询的执行(像往常一样)被延迟,直到有东西尝试迭代。基本上,“Any()”尝试遍历集合,因此,它执行 Linq 查询。
  • 查看延迟表达式,“.Select(x => this[x])”部分是罪魁祸首。它调用“this[string cellAddress]”,在“cellRef.Row > WorksheetDimension.BottomRight.Row”的情况下抛出“IndexOutOfRangeException”,如果您尝试访问超出范围的行,就会出现这种情况。不确定它是否可以被视为一个错误......但我同意延迟异常是不直观的。
  • LightweightExcelReader 的作者在这里。我同意 DarkCompiled 的方法 - 在尝试访问行索引之前检查 SheetReader 的 MaxRow 属性。是的,这不是一个错误,但是当您在可枚举上调用 Any() 时抛出异常肯定不直观。我对version 0.1.15-beta 进行了更改,以便在您调用SheetReader.Row() 时抛出IndexOutOfRangeException,而不是在评估可枚举时。
猜你喜欢
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多