GVKun编程网logo

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?(indexoutofrangeexception异常)

15

对于想了解什么是IndexOutOfRangeException/ArgumentOutOfRangeException,我该如何解决?的读者,本文将是一篇不可错过的文章,我们将详细介绍indexou

对于想了解什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?的读者,本文将是一篇不可错过的文章,我们将详细介绍indexoutofrangeexception异常,并且为您提供关于ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置、arraylist OutOfRangeException 上的异常、asp.net – 将MemoryCache与HostFileChangeMonitor init一起使用到目录获取ArgumentOutOfRangeException、C# DirectorySearcher.FindOne();得到 thores ArgumentOutOfRangeException的有价值信息。

本文目录一览:

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?(indexoutofrangeexception异常)

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?(indexoutofrangeexception异常)

我有一些代码,当它执行时,它会抛出一个IndexOutOfRangeException,说,

指数数组的边界之外。

这是什么意思,我能做些什么呢?

根据使用的类,它也可以是ArgumentOutOfRangeException

mscorlib.dll
中出现“System.ArgumentOutOfRangeException”类型的异常,但未在用户代码中处理附加信息:索引超出范围。必须是非负数且小于集合的大小。

答案1

小编典典

它是什么?

此异常意味着您尝试使用无效索引按索引访问集合项。当索引低于集合的下限或大于或等于它包含的元素数时,索引无效。

当它被抛出

给定一个声明为的数组:

byte[] array = new byte[4];

您可以从 0 到 3 访问此数组,超出此范围的值将导致IndexOutOfRangeException被抛出。在创建和访问数组时记住这一点。

数组长度
在 C# 中,数组通常是从 0 开始的。这意味着第一个元素的索引为 0,最后一个元素的索引为Length -1(其中Length是数组中的项目总数),因此此代码不起作用:

array[array.Length] = 0;

此外请注意,如果您有一个多维数组,那么您不能同时使用Array.Length这两个维度,您必须使用Array.GetLength()

int[,] data = new int[10, 5];for (int i=0; i < data.GetLength(0); ++i) {    for (int j=0; j < data.GetLength(1); ++j) {        data[i, j] = 1;    }}

上界不包含在内
在下面的示例中,我们创建一个原始二维数组Color。每个项目代表一个像素,索引是从(0, 0)(imageWidth - 1,imageHeight - 1)

Color[,] pixels = new Color[imageWidth, imageHeight];for (int x = 0; x <= imageWidth; ++x) {    for (int y = 0; y <= imageHeight; ++y) {        pixels[x, y] = backgroundColor;    }}

然后此代码将失败,因为数组是基于 0 的并且图像中的最后一个(右下)像素是pixels[imageWidth - 1, imageHeight -1]

pixels[imageWidth, imageHeight] = Color.Black;

在另一种情况下,您可能会获得ArgumentOutOfRangeException此代码(例如,如果您在类上使用GetPixel方法Bitmap)。

数组不会增长
数组很快。与其他所有集合相比,线性搜索非常快。这是因为项目在内存中是连续的,因此可以计算内存地址(并且增量只是一个加法)。无需遵循节点列表,简单的数学运算!您为此付出了一个限制:它们不能增长,如果您需要更多元素,则需要重新分配该数组(如果必须将旧项目复制到新块,这可能需要相对较长的时间)。您使用
调整它们的大小Array.Resize<T>(),此示例将新条目添加到现有数组:

Array.Resize(ref array, array.Length + 1);

不要忘记有效的索引是 from 0to Length -1。如果您只是尝试分配一个项目,Length您将得到IndexOutOfRangeException(如果您认为它们可能会使用类似于Insert其他集合的方法的语法增加,这种行为可能会让您感到困惑)。

__具有自定义下界的 特殊
数组 数组中的第一项始终具有索引 0 。这并不总是正确的,因为您可以创建一个具有自定义下限的数组:

var array = Array.CreateInstance(typeof(byte), new int[] { 4 }, new int[] { 1 });

在该示例中,数组索引从 1 到 4 有效。当然,上限不能更改。

错误的参数
如果您使用未经验证的参数(来自用户输入或函数用户)访问数组,您可能会收到以下错误:

private static string[] RomanNumbers =    new string[] { "I", "II", "III", "IV", "V" };public static string Romanize(int number){    return RomanNumbers[number];}

意外结果
这个异常也可能由于另一个原因引发:按照惯例,如果没有,许多 搜索函数 将返回 -1(.NET 2.0
引入了可空值,无论如何这也是多年来使用的众所周知的约定)找不到任何东西。让我们假设您有一个与字符串相当的对象数组。你可能会想写这段代码:

// Items comparable with a stringConsole.WriteLine("First item equals to ''Debug'' is ''{0}''.",    myArray[Array.IndexOf(myArray, "Debug")]);// Arbitrary objectsConsole.WriteLine("First item equals to ''Debug'' is ''{0}''.",    myArray[Array.FindIndex(myArray, x => x.Type == "Debug")]);

如果没有项目myArray满足搜索条件,这将失败,因为Array.IndexOf()将返回 -1,然后数组访问将抛出。

下一个示例是一个简单的示例,用于计算给定数字集的出现次数(知道最大数量并返回一个数组,其中索引 0 处的项目表示数字 0,索引 1 处的项目表示数字
1,依此类推):

static int[] CountOccurences(int maximum, IEnumerable<int> numbers) {    int[] result = new int[maximum + 1]; // Includes 0    foreach (int number in numbers)        ++result[number];    return result;}

当然,这是一个非常糟糕的实现,但我想展示的是,对于负数和上面的数字,它会失败maximum

它如何适用于List<T>

与数组相同的情况 - 有效索引的范围 - 0(List的索引始终以 0 开头)到list.Count- 访问此范围之外的元素将导致异常。

请注意,对于数组List<T>使用.ArgumentOutOfRangeException``IndexOutOfRangeException

与数组不同,List<T>开始为空 - 因此尝试访问刚刚创建的列表中的项目会导致此异常。

var list = new List<int>();

常见情况是使用索引填充列表(类似于Dictionary<int, T>)会导致异常:

list[0] = 42; // exceptionlist.Add(42); // correct

IDataReader 和 Columns
假设您正尝试使用以下代码从数据库中读取数据:

using (var connection = CreateConnection()) {    using (var command = connection.CreateCommand()) {        command.CommandText = "SELECT MyColumn1, MyColumn2 FROM MyTable";        using (var reader = command.ExecuteReader()) {            while (reader.Read()) {                ProcessData(reader.GetString(2)); // Throws!            }        }    }}

GetString()会抛出IndexOutOfRangeException,因为您的数据集只有两列,但您试图从第三列获取值(索引 始终 从0
开始)。

请注意,此行为与大多数IDataReader实现共享(SqlDataReader等等OleDbDataReader)。

如果您使用索引器运算符的 IDataReader 重载,该运算符采用列名并传递无效的列名,您也可以获得相同的异常。
例如,假设您检索了一个名为 Column1 的列,但是您尝试使用以下命令检索该字段的值

 var data = dr["Colum1"];  // Missing the n in Column1.

发生这种情况是因为实现了索引器运算符,试图检索不存在的 Colum1字段的索引。 当 GetOrdinal 方法的内部帮助代码返回 -1
作为“Colum1”的索引时,将引发此异常。

其他
抛出此异常时还有另一种(记录在案的)情况:如果在 中DataView,提供给DataViewSort属性的数据列名称无效。

如何避免

在这个例子中,为了简单起见,我假设数组总是一维的并且从 0
开始。如果你想严格一点(或者你正在开发一个库),你可能需要用0withGetLowerBound(0).Lengthwith替换GetUpperBound(0)(当然如果你有System.Array
类型的参数,它不适用于T[])。请注意,在这种情况下,上限包括以下代码:

for (int i=0; i < array.Length; ++i) { }

应该这样改写:

for (int i=array.GetLowerBound(0); i <= array.GetUpperBound(0); ++i) { }

请注意,这是不允许的(它会抛出InvalidCastException),这就是为什么如果您的参数是T[]您对自定义下限数组是安全的:

void foo<T>(T[] array) { }void test() {    // This will throw InvalidCastException, cannot convert Int32[] to Int32[*]    foo((int)Array.CreateInstance(typeof(int), new int[] { 1 }, new int[] { 1 }));}

验证参数
如果 index 来自一个参数,您应该始终验证它们(抛出适当的ArgumentExceptionor
ArgumentOutOfRangeException)。在下一个示例中,错误的参数可能会导致IndexOutOfRangeException,此函数的用户可能会期望这一点,因为他们正在传递一个数组,但这并不总是那么明显。我建议始终验证公共函数的参数:

static void SetRange<T>(T[] array, int from, int length, Func<i, T> function){    if (from < 0 || from>= array.Length)        throw new ArgumentOutOfRangeException("from");    if (length < 0)        throw new ArgumentOutOfRangeException("length");    if (from + length > array.Length)        throw new ArgumentException("...");    for (int i=from; i < from + length; ++i)        array[i] = function(i);}

如果函数是私有的,您可以简单地将if逻辑替换为Debug.Assert()

Debug.Assert(from >= 0 && from < array.Length);

检查对象状态
数组索引可能不是直接来自一个参数。它可能是对象状态的一部分。一般来说,验证对象状态始终是一种很好的做法(如果需要,可以单独验证对象状态,也可以使用函数参数)。您可以使用Debug.Assert()、抛出一个适当的异常(更能描述问题)或像本例中那样处理:

class Table {    public int SelectedIndex { get; set; }    public Row[] Rows { get; set; }    public Row SelectedRow {        get {            if (Rows == null)                throw new InvalidOperationException("...");            // No or wrong selection, here we just return null for            // this case (it may be the reason we use this property            // instead of direct access)            if (SelectedIndex < 0 || SelectedIndex >= Rows.Length)                return null;            return Rows[SelectedIndex];        }}

验证返回值
在前面的一个例子中,我们直接使用了Array.IndexOf()返回值。如果我们知道它可能会失败,那么最好处理这种情况:

int index = myArray[Array.IndexOf(myArray, "Debug");if (index != -1) { } else { }

如何调试

在我看来,关于这个错误的大多数问题都可以简单地避免。你花在写一个正确的问题上的时间(带有一个小的工作示例和一个小的解释)可能比你调试代码所需的时间要多得多。首先,阅读
Eric Lippert 的这篇关于调试小程序的博文,我不会在这里重复他的话,但它绝对是 必读 的。

您有源代码,您有带有堆栈跟踪的异常消息。去那里,选择正确的行号,你会看到:

array[index] = newValue;

你发现你的错误,检查如何index增加。这样对吗?查看数组是怎么分配的,是怎么index加的?根据您的规格是否正确?如果您对所有这些问题的回答都是
肯定 的,那么您会在 StackOverflow 上找到很好的帮助,但请先自行检查。您将节省自己的时间!

一个好的起点是始终使用断言并验证输入。你甚至可能想要使用代码契约。当出现问题并且您无法通过快速查看代码来弄清楚发生了什么时,您必须求助于一个老朋友:
调试器 。只需在 Visual Studio(或您最喜欢的
IDE)中的调试中运行您的应用程序,您就会确切地看到哪一行引发了此异常,涉及哪个数组以及您尝试使用哪个索引。真的,99% 的时间你会在几分钟内自己解决。

如果在生产中发生这种情况,那么您最好在有罪的代码中添加断言,可能我们不会在您的代码中看到您自己看不到的内容(但您总是可以打赌)。

VB.NET 的故事

我们在 C# 答案中所说的所有内容都适用于具有明显语法差异的 VB.NET,但是在处理 VB.NET 数组时需要考虑一个重要的点。

在 VB.NET 中,数组被声明为设置数组的最大有效索引值。这不是我们要存储在数组中的元素的数量。

'' declares an array with space for 5 integer '' 4 is the maximum valid index starting from 0 to 4Dim myArray(4) as Integer

所以这个循环将用 5 个整数填充数组,而不会导致任何 IndexOutOfRangeException

For i As Integer = 0 To 4    myArray(i) = iNext

VB.NET 规则

此异常意味着您尝试使用无效索引按索引访问集合项。当索引低于集合的下限或大于时,索引无效 等于它包含的元素数量。 数组声明中定义的最大允许索引

ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置

ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置

如何解决ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置?

我的脚本有问题,如果有人能提供帮助,我将不胜感激。

问题来了:

ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置。 参数名称:长度 System.String.Substring (system.int32 startIndex,system.int32 length) (at :0)

脚本是:

 public class ColorTypeConverter
 {
     public string ToRGBHex(Color c)
     {
         return string.Format("{0:X2}{1:X2}{2:X2}",ToByte(c.r),ToByte(c.g),ToByte(c.b));
     }
 
     private static byte ToByte(float f)
     {
         f = Mathf.Clamp01(f);
         return (byte)(f * 255);
     }
     
    private int HexToDec (string hex)
    {
        int dec = System.Convert.ToInt32(hex,16);
        return dec;
    }
    
    private float HexToFloatnormalized(string hex) {
        return HexToDec(hex) / 255f;
    }

    public Color GetColorFromString(string hexString) {
        float red = HexToFloatnormalized(hexString.Substring(0,2));
        float green = HexToFloatnormalized(hexString.Substring(2,2));
        float blue = HexToFloatnormalized(hexString.Substring(4,2));
        return new Color(red,green,blue);
    }
 }

UI 管理器脚本:

string s = PlayerPrefs.GetString("savecolorground");
ColorTypeConverter col = new ColorTypeConverter();
if(s != "")
    ground.GetComponent<SpriteRenderer>().color = col.GetColorFromString(s);
else
    ground.GetComponent<SpriteRenderer>().color = col.GetColorFromString("FFFFFF");

播放器脚本:

ColorTypeConverter colCon = new ColorTypeConverter();
string color = PlayerPrefs.GetString("savecolor");  
if(color != "")
    GetComponent<SpriteRenderer>().color = colCon.GetColorFromString(color);
else
    GetComponent<SpriteRenderer>().color = colCon.GetColorFromString("2AFCFF");

GetComponent<TrailRenderer>().startColor = new Color(
    GetComponent<SpriteRenderer>().color.r,GetComponent<SpriteRenderer>().color.g,GetComponent<SpriteRenderer>().color.b,255);

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

arraylist OutOfRangeException 上的异常

arraylist OutOfRangeException 上的异常

如何解决arraylist OutOfRangeException 上的异常?

首先,我将一个 ArrayList 初始化到我的代码中,然后添加用户的每个输入。我设法添加了数据并显示,但这样做后它抛出了 OutOfRange 异常,我看不出任何原因。

我已经问过类似的问题,但它是为了检查数组是否已存储值 Link to my first question。但是我现在遇到的问题就是这个异常

static ArrayList fName = new ArrayList();
static ArrayList cNumber = new ArrayList();

public static void createContact()
{
    Console.Write("\nEnter your full name: ");
    fullName = Console.ReadLine();
    fName.Add(fullName);

    Console.Write("\nEnter your contact number: ");
    contactNumber = Console.ReadLine();
    cNumber.Add(contactNumber);
}

public static void displayContact()
{
    if (fName.Count == 0 && cNumber.Count == 0)
    {
        Console.WriteLine("No Data Yet!");
    }

    else if (fName.Count > 0 && cNumber.Count > 0)
    {
        for (int j = 0; j < numbers.Length; j++)
        {
            Console.WriteLine(numbers[j] + ". " + fName[j] + " - " + cNumber[j]);
        }
    }

    else if (fName.Count <= 10 && cNumber.Count <= 10)
    {
        Console.WriteLine("Maximum data acquired! Terminating program...");
    }
}

输出如下:

Output 1

Output 2

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

asp.net – 将MemoryCache与HostFileChangeMonitor init一起使用到目录获取ArgumentOutOfRangeException

asp.net – 将MemoryCache与HostFileChangeMonitor init一起使用到目录获取ArgumentOutOfRangeException

我正在使用.NET 4的System.Runtime.Caching中的MemoryCache,我希望在目录更改时使缓存条目无效.

HostFileChangeMonitor应该处理文件和目录,所以我这样添加它:

var cacheItemPolicy = new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(30) };
cacheItemPolicy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string> { folder }));

但后来我得到一个例外:

System.ArgumentOutOfRangeException: The UTC time represented when the offset is applied must be between year 0 and 10,000.

只有在ASP.NET网站中使用代码时才会发生这种情况.它在控制台应用程序中运行良好.

我在ms连接上找到了this,但我添加到HostFileChangeMonitor的目录存在.

谢谢你的帮助.

解决方法

回答我自己的问题:  将目录添加到HostFileChangeMonitor时似乎4.0有一个错误.

C# DirectorySearcher.FindOne();得到 thores ArgumentOutOfRangeException

C# DirectorySearcher.FindOne();得到 thores ArgumentOutOfRangeException

如何解决C# DirectorySearcher.FindOne();得到 thores ArgumentOutOfRangeException?

我正在尝试使用安全的 LDAP 查询来验证用户。我的代码在调用时抛出异常

SearchResult result = search.FindOne;

代码:

public LDAPDto LDAPLogin1(string userName,string mima)
    {
        string domainName = System.Configuration.ConfigurationManager.AppSettings["LDAPDomainName"];
        string _path = System.Configuration.ConfigurationManager.AppSettings["LDAPPath"];
        PrincipalContext ADCHECK = null;
        try
        {
            ADCHECK = new PrincipalContext(ContextType.Domain,domainName);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        if (!ADCHECK.ValidateCredentials(userName,mima,ContextOptions.Negotiate))
        {
            return new LDAPDto() { IsLogin = false };
        }
        string domainAndUsername = domainName + @"\" + userName;
        DirectoryEntry entry = new DirectoryEntry(_path,domainAndUsername,mima);
        DirectorySearcher search = null;
        try
        {
            search = new DirectorySearcher(entry);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        try
        {
            search.Filter = "(SAMAccountName=" + userName + ")";
        }
        catch (Exception ex)
        {
            throw ex;
        }
        search.PropertiesToLoad.AddRange(new string[] { "sn","givenname","displayName","title","department" });
        SearchResult result;
        try
        {
            result = search.FindOne();
            result.GetDirectoryEntry();
        }
        catch (Exception ex)
        {
            //there throw ex
            throw ex;
        }
        var user = new LDAPDto()
        {
            IsLogin = true,Img = null,Sn = (string)result.Properties["sn"][0],Title = (string)result.Properties["title"][0],Givenname = (string)result.Properties["givenname"][0],displayName = (string)result.Properties["displayName"][0],Department = (string)result.Properties["department"][0],};
        return user;
    }

但我不明白(我的广告是否设置了:“sn”、“givenname”、“displayName”、“title”、“department”这些值,并且它可以工作,其他广告成员只是设置了“sn” ","displayName" / "title","department" 为空,我失败了)

是否有任何重新扫描失败?

ArgumentOutOfRangeException:索引超出范围。必须是非负的并且小于集合的大小。参数名称:index.

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

关于什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?indexoutofrangeexception异常的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于ArgumentOutOfRangeException:索引和长度必须引用字符串中的某个位置、arraylist OutOfRangeException 上的异常、asp.net – 将MemoryCache与HostFileChangeMonitor init一起使用到目录获取ArgumentOutOfRangeException、C# DirectorySearcher.FindOne();得到 thores ArgumentOutOfRangeException的相关信息,请在本站寻找。

本文标签: