Lire en anglais

Partager via


IndexOutOfRangeException Classe

Définition

Exception levée lors d’une tentative d’accès à un élément d’un tableau ou d’une collection ayant un index en dehors de ses limites.

C#
public sealed class IndexOutOfRangeException : Exception
C#
public sealed class IndexOutOfRangeException : SystemException
C#
[System.Serializable]
public sealed class IndexOutOfRangeException : SystemException
C#
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class IndexOutOfRangeException : SystemException
Héritage
IndexOutOfRangeException
Héritage
IndexOutOfRangeException
Attributs

Remarques

Une IndexOutOfRangeException exception est levée lorsqu’un index non valide est utilisé pour accéder à un membre d’un tableau ou d’une collection, ou pour lire ou écrire à partir d’un emplacement particulier dans une mémoire tampon. Cette exception hérite de la Exception classe, mais n’ajoute aucun membre unique.

En règle générale, une IndexOutOfRangeException exception est levée suite à une erreur du développeur. Au lieu de gérer l’exception, vous devez diagnostiquer la cause de l’erreur et corriger votre code. Les causes les plus courantes de l’erreur sont les suivantes :

  • Oubliant que la limite supérieure d’une collection ou d’un tableau de base zéro est inférieure à son nombre de membres ou d’éléments, comme l’illustre l’exemple suivant.

    C#
    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       public static void Main()
       {
          List<Char> characters = new List<Char>();
          characters.InsertRange(0, new Char[] { 'a', 'b', 'c', 'd', 'e', 'f' } );
          for (int ctr = 0; ctr <= characters.Count; ctr++)
             Console.Write("'{0}'    ", characters[ctr]);
       }
    }
    // The example displays the following output:
    //    'a'    'b'    'c'    'd'    'e'    'f'
    //    Unhandled Exception:
    //    System.ArgumentOutOfRangeException:
    //    Index was out of range. Must be non-negative and less than the size of the collection.
    //    Parameter name: index
    //       at Example.Main()
    

    Pour corriger l’erreur, vous pouvez utiliser du code comme suit.

    C#
    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       public static void Main()
       {
          List<Char> characters = new List<Char>();
          characters.InsertRange(0, new Char[] { 'a', 'b', 'c', 'd', 'e', 'f' } );
          for (int ctr = 0; ctr < characters.Count; ctr++)
             Console.Write("'{0}'    ", characters[ctr]);
       }
    }
    // The example displays the following output:
    //        'a'    'b'    'c'    'd'    'e'    'f'
    

    Sinon, au lieu d’itérer tous les éléments du tableau par leur index, vous pouvez utiliser l’instruction foreach (en C#), l’instruction for...in (en F#) ou l’instruction For Each (en Visual Basic).

  • Tentative d’affectation d’un élément de tableau à un autre tableau qui n’a pas été correctement dimensionné et qui a moins d’éléments que le tableau d’origine. L’exemple suivant tente d’affecter le dernier élément du value1 tableau au même élément du value2 tableau. Toutefois, le value2 tableau a été mal dimensionné pour avoir six éléments au lieu de sept éléments. Par conséquent, l’affectation lève une IndexOutOfRangeException exception.

    C#
    public class Example
    {
       public static void Main()
       {
          int[] values1 = { 3, 6, 9, 12, 15, 18, 21 };
          int[] values2 = new int[6];
    
          // Assign last element of the array to the new array.
          values2[values1.Length - 1] = values1[values1.Length - 1];
       }
    }
    // The example displays the following output:
    //       Unhandled Exception:
    //       System.IndexOutOfRangeException:
    //       Index was outside the bounds of the array.
    //       at Example.Main()
    
  • Utilisation d’une valeur retournée par une méthode de recherche pour itérer une partie d’un tableau ou d’une collection commençant à une position d’index particulière. Si vous oubliez de vérifier si l’opération de recherche a trouvé une correspondance, le runtime lève une IndexOutOfRangeException exception, comme illustré dans cet exemple.

    C#
    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       static List<int> numbers = new List<int>();
    
       public static void Main()
       {
          int startValue;
          string[] args = Environment.GetCommandLineArgs();
          if (args.Length < 2)
             startValue = 2;
          else
             if (! Int32.TryParse(args[1], out startValue))
                startValue = 2;
    
          ShowValues(startValue);
       }
    
       private static void ShowValues(int startValue)
       {
          // Create a collection with numeric values.
          if (numbers.Count == 0)
             numbers.AddRange( new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22} );
    
          // Get the index of a startValue.
          Console.WriteLine("Displaying values greater than or equal to {0}:",
                            startValue);
          int startIndex = numbers.IndexOf(startValue);
          // Display all numbers from startIndex on.
          for (int ctr = startIndex; ctr < numbers.Count; ctr++)
             Console.Write("    {0}", numbers[ctr]);
       }
    }
    // The example displays the following output if the user supplies
    // 7 as a command-line parameter:
    //    Displaying values greater than or equal to 7:
    //
    //    Unhandled Exception: System.ArgumentOutOfRangeException:
    //    Index was out of range. Must be non-negative and less than the size of the collection.
    //    Parameter name: index
    //       at System.Collections.Generic.List`1.get_Item(Int32 index)
    //       at Example.ShowValues(Int32 startValue)
    //       at Example.Main()
    

    Dans ce cas, la List<T>.IndexOf méthode retourne -1, qui est une valeur d’index non valide, lorsqu’elle ne parvient pas à trouver une correspondance. Pour corriger cette erreur, vérifiez la valeur de retour de la méthode de recherche avant d’itérer le tableau, comme illustré dans cet exemple.

    C#
    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       static List<int> numbers = new List<int>();
    
       public static void Main()
       {
          int startValue;
          string[] args = Environment.GetCommandLineArgs();
          if (args.Length < 2)
             startValue = 2;
          else
             if (! Int32.TryParse(args[1], out startValue))
                startValue = 2;
    
          ShowValues(startValue);
       }
    
       private static void ShowValues(int startValue)
       {
          // Create a collection with numeric values.
          if (numbers.Count == 0)
             numbers.AddRange( new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22} );
    
          // Get the index of startValue.
          int startIndex = numbers.IndexOf(startValue);
          if (startIndex < 0) {
             Console.WriteLine("Unable to find {0} in the collection.", startValue);
          }
          else {
             // Display all numbers from startIndex on.
             Console.WriteLine("Displaying values greater than or equal to {0}:",
                            startValue);
             for (int ctr = startIndex; ctr < numbers.Count; ctr++)
                Console.Write("    {0}", numbers[ctr]);
          }
       }
    }
    // The example displays the following output if the user supplies
    // 7 as a command-line parameter:
    //      Unable to find 7 in the collection.
    
  • Essayez d’utiliser ou d’énumérer un jeu de résultats, une collection ou un tableau retourné par une requête sans tester si l’objet retourné a des données valides.

  • Utilisation d’une valeur calculée pour définir l’index de départ, l’index de fin ou le nombre d’éléments à itérer. Si le résultat du calcul est inattendu, cela peut entraîner une IndexOutOfRangeException exception. Vous devez vérifier la logique de votre programme pour calculer la valeur d’index et valider la valeur avant d’itérer le tableau ou la collection. Les conditions suivantes doivent toutes être remplies ; sinon, une IndexOutOfRangeException exception est levée :

    • L’index de départ doit être supérieur ou égal à Array.GetLowerBound la dimension du tableau à itérer, ou supérieur ou égal à 0 pour une collection.

    • L’index de fin ne peut pas dépasser Array.GetUpperBound la dimension du tableau que vous souhaitez itérer, ou ne peut pas être supérieur ou égal à la Count propriété d’une collection.

    • L’équation suivante doit être vraie pour la dimension du tableau que vous souhaitez itérer :

      start_index >= lower_bound And start_index + items_to_iterate - 1 <= upper_bound  
      

      Pour une collection, l’équation suivante doit être vraie :

      start_index >= 0 And start_index + items_to_iterate <= Count  
      

      Conseil

      L’index de départ d’un tableau ou d’une collection ne peut jamais être un nombre négatif.

  • En supposant qu’un tableau doit être de base zéro. Les tableaux qui ne sont pas de base zéro peuvent être créés par la Array.CreateInstance(Type, Int32[], Int32[]) méthode et peuvent être retournés par COM Interop, bien qu’ils ne soient pas conformes CLS. L’exemple suivant illustre ce IndexOutOfRangeException qui est levée lorsque vous essayez d’itérer un tableau autre que zéro créé par la Array.CreateInstance(Type, Int32[], Int32[]) méthode.

    C#
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Array values = Array.CreateInstance(typeof(int), new int[] { 10 },
                                              new int[] { 1 });
          int value = 2;
          // Assign values.
          for (int ctr = 0; ctr < values.Length; ctr++) {
             values.SetValue(value, ctr);
             value *= 2;
          }
    
          // Display values.
          for (int ctr = 0; ctr < values.Length; ctr++)
             Console.Write("{0}    ", values.GetValue(ctr));
       }
    }
    // The example displays the following output:
    //    Unhandled Exception:
    //    System.IndexOutOfRangeException: Index was outside the bounds of the array.
    //       at System.Array.InternalGetReference(Void* elemRef, Int32 rank, Int32* pIndices)
    //       at System.Array.SetValue(Object value, Int32 index)
    //       at Example.Main()
    

    Pour corriger l’erreur, comme dans l’exemple suivant, vous pouvez appeler la GetLowerBound méthode au lieu d’effectuer des hypothèses sur l’index de départ d’un tableau.

    C#
    using System;
    
    public class Example
    {
       public static void Main()
       {
          Array values = Array.CreateInstance(typeof(int), new int[] { 10 },
                                              new int[] { 1 });
          int value = 2;
          // Assign values.
          for (int ctr = values.GetLowerBound(0); ctr <= values.GetUpperBound(0); ctr++) {
             values.SetValue(value, ctr);
             value *= 2;
          }
    
          // Display values.
          for (int ctr = values.GetLowerBound(0); ctr <= values.GetUpperBound(0); ctr++)
             Console.Write("{0}    ", values.GetValue(ctr));
       }
    }
    // The example displays the following output:
    //        2    4    8    16    32    64    128    256    512    1024
    

    Notez que lorsque vous appelez la GetLowerBound méthode pour obtenir l’index de départ d’un tableau, vous devez également appeler la Array.GetUpperBound(Int32) méthode pour obtenir son index de fin.

  • Confusion d’un index et de la valeur à cet index dans un tableau numérique ou une collection. Ce problème se produit généralement lors de l’utilisation de l’instruction foreach (en C#), de l’instruction for...in (en F#) ou de l’instruction For Each (en Visual Basic). L'exemple de code suivant illustre le problème.

    C#
    using System;
    
    public class Example
    {
       public static void Main()
       {
          // Generate array of random values.
          int[] values = PopulateArray(5, 10);
          // Display each element in the array.
          foreach (var value in values)
             Console.Write("{0}   ", values[value]);
       }
    
       private static int[] PopulateArray(int items, int maxValue)
       {
          int[] values = new int[items];
          Random rnd = new Random();
          for (int ctr = 0; ctr < items; ctr++)
             values[ctr] = rnd.Next(0, maxValue + 1);
    
          return values;
       }
    }
    // The example displays output like the following:
    //    6   4   4
    //    Unhandled Exception: System.IndexOutOfRangeException:
    //    Index was outside the bounds of the array.
    //       at Example.Main()
    

    La construction d’itération retourne chaque valeur d’un tableau ou d’une collection, et non son index. Pour éliminer l’exception, utilisez ce code.

    C#
    using System;
    
    public class Example
    {
       public static void Main()
       {
          // Generate array of random values.
          int[] values = PopulateArray(5, 10);
          // Display each element in the array.
          foreach (var value in values)
             Console.Write("{0}   ", value);
       }
    
       private static int[] PopulateArray(int items, int maxValue)
       {
          int[] values = new int[items];
          Random rnd = new Random();
          for (int ctr = 0; ctr < items; ctr++)
             values[ctr] = rnd.Next(0, maxValue + 1);
    
          return values;
       }
    }
    // The example displays output like the following:
    //        10   6   7   5   8
    
  • Fourniture d’un nom de colonne non valide à la DataView.Sort propriété.

  • Violation de la sécurité des threads. Les opérations telles que la lecture à partir du même StreamReader objet, l’écriture dans le même StreamWriter objet à partir de plusieurs threads ou l’énumération des objets d’un Hashtable thread différent peuvent lever une IndexOutOfRangeException exception si l’objet n’est pas accessible de manière thread-safe. Cette exception est généralement intermittente, car elle s’appuie sur une condition de concurrence.

L’utilisation de valeurs d’index codées en dur pour manipuler un tableau est susceptible de lever une exception si la valeur d’index est incorrecte ou non valide, ou si la taille du tableau en cours de manipulation est inattendue. Pour empêcher une opération de lever une IndexOutOfRangeException exception, vous pouvez effectuer les opérations suivantes :

  • Itérer les éléments du tableau à l’aide de l’instruction foreach (en C#), le for... in statement (in F#), or the For Each... Construction suivante (dans Visual Basic) au lieu d’itérer des éléments par index.

  • Itérer les éléments par index commençant par l’index retourné par la Array.GetLowerBound méthode et se terminant par l’index retourné par la Array.GetUpperBound méthode.

  • Si vous affectez des éléments d’un tableau à un autre, assurez-vous que le tableau cible a au moins autant d’éléments que le tableau source en comparant leurs Array.Length propriétés.

Pour obtenir la liste des valeurs initiales des propriétés d’une instance de IndexOutOfRangeException, consultez le IndexOutOfRangeException constructeurs.

Les instructions de langage intermédiaire (IL) suivantes lèvent IndexOutOfRangeException:

  • ldelem.<type>

  • ldelema

  • stelem.<type>

IndexOutOfRangeException utilise le COR_E_INDEXOUTOFRANGE HRESULT, qui a la valeur 0x80131508.

Constructeurs

IndexOutOfRangeException()

Initialise une nouvelle instance de la classe IndexOutOfRangeException.

IndexOutOfRangeException(String)

Initialise une nouvelle instance de la classe IndexOutOfRangeException avec un message d'erreur spécifié.

IndexOutOfRangeException(String, Exception)

Initialise une nouvelle instance de la classe IndexOutOfRangeException avec un message d'erreur spécifié et une référence à l'exception interne ayant provoqué cette exception.

Propriétés

Data

Obtient une collection de paires clé/valeur qui fournissent des informations définies par l'utilisateur supplémentaires sur l'exception.

(Hérité de Exception)
HelpLink

Obtient ou définit un lien vers le fichier d'aide associé à cette exception.

(Hérité de Exception)
HResult

Obtient ou définit HRESULT, valeur numérique codée qui est assignée à une exception spécifique.

(Hérité de Exception)
InnerException

Obtient l'instance Exception qui a provoqué l'exception actuelle.

(Hérité de Exception)
Message

Obtient un message qui décrit l'exception active.

(Hérité de Exception)
Source

Obtient ou définit le nom de l'application ou de l'objet qui est à l'origine de l'erreur.

(Hérité de Exception)
StackTrace

Obtient une représentation sous forme de chaîne des frames immédiats sur la pile des appels.

(Hérité de Exception)
TargetSite

Obtient la méthode qui lève l'exception actuelle.

(Hérité de Exception)

Méthodes

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.

(Hérité de Object)
GetBaseException()

En cas de substitution dans une classe dérivée, retourne la Exception qui est à l'origine d'une ou de plusieurs exceptions ultérieures.

(Hérité de Exception)
GetHashCode()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetObjectData(SerializationInfo, StreamingContext)

En cas de substitution dans une classe dérivée, définit SerializationInfo avec des informations sur l'exception.

(Hérité de Exception)
GetType()

Obtient le type au moment de l'exécution de l'instance actuelle.

(Hérité de Exception)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
ToString()

Crée et retourne une chaîne représentant l'exception actuelle.

(Hérité de Exception)

Événements

SerializeObjectState
Obsolète.

Se produit quand une exception est sérialisée pour créer un objet d'état d'exception qui contient des données sérialisées concernant l'exception.

(Hérité de Exception)

S’applique à

Produit Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Voir aussi