ArgumentOutOfRangeException Класс

Определение

Исключение, которое выдается, если значение аргумента не соответствует допустимому диапазону значений, установленному вызванным методом.

public ref class ArgumentOutOfRangeException : ArgumentException
public class ArgumentOutOfRangeException : ArgumentException
[System.Serializable]
public class ArgumentOutOfRangeException : ArgumentException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class ArgumentOutOfRangeException : ArgumentException
type ArgumentOutOfRangeException = class
    inherit ArgumentException
type ArgumentOutOfRangeException = class
    inherit ArgumentException
    interface ISerializable
[<System.Serializable>]
type ArgumentOutOfRangeException = class
    inherit ArgumentException
    interface ISerializable
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type ArgumentOutOfRangeException = class
    inherit ArgumentException
    interface ISerializable
Public Class ArgumentOutOfRangeException
Inherits ArgumentException
Наследование
ArgumentOutOfRangeException
Наследование
ArgumentOutOfRangeException
Атрибуты
Реализации

Примеры

В следующем примере определяется класс, содержащий сведения о приглашенном госте. Если гость имеет значение моложе 21, ArgumentOutOfRangeException возникает исключение.

using System;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Guest guest1 = new Guest("Ben", "Miller", 17);
            Console.WriteLine(guest1.GuestInfo());
        }
        catch (ArgumentOutOfRangeException outOfRange)
        {

            Console.WriteLine("Error: {0}", outOfRange.Message);
        }
    }
}

class Guest
{
    private string FirstName;
    private string LastName;
    private int Age;

    public Guest(string fName, string lName, int age)
    {
        FirstName = fName;
        LastName = lName;
        if (age < 21)
            throw new ArgumentOutOfRangeException("age","All guests must be 21-years-old or older.");
        else
            Age = age;
    }

    public string GuestInfo()
    {
        string gInfo = FirstName + " " + LastName + ", " + Age.ToString();
        return(gInfo);
    }
}
Module Module1
   Public Sub Main()
       Try
           Dim guest1 As Guest = New Guest("Ben", "Miller", 17)
           Console.WriteLine(guest1.GuestInfo)
       Catch outOfRange As ArgumentOutOfRangeException
           Console.WriteLine("Error: {0}", outOfRange.Message)
       End Try
   End Sub
End Module

Class Guest
    Private FirstName As String
    Private LastName As String
    Private Age As Integer

    Public Sub New(ByVal fName As String, ByVal lName As String, ByVal age As Integer)
        MyBase.New()
        FirstName = fName
        LastName = lName
        If (age < 21) Then
            Throw New ArgumentOutOfRangeException("age", "All guests must be 21-years-old or older.")
        Else
            age = age
        End If
    End Sub

    Public Function GuestInfo() As String
        Dim gInfo As String = (FirstName + (" " _
                    + (Me.LastName + (", " + Me.Age.ToString))))
        Return gInfo
    End Function
End Class

Комментарии

ArgumentOutOfRangeExceptionИсключение возникает при вызове метода, а по крайней мере один из аргументов, передаваемых в метод, — не null и содержит недопустимое значение, которое не является элементом набора значений, ожидаемых для аргумента. ParamNameСвойство определяет недопустимый аргумент, а ActualValue свойство, если значение указано, определяет недопустимое значение.

Как правило, в ArgumentOutOfRangeException результате ошибки разработчика. Вместо обработки исключения в try / catch блоке следует устранить причину исключения или, если аргумент возвращается вызовом метода или входными данными пользователя перед передачей в метод, порождающий исключение, перед передачей в метод необходимо проверить аргументы.

ArgumentOutOfRangeException широко используется:

Ниже перечислены условия, в которых ArgumentOutOfRangeException создается исключение.

  • Вы получаете член коллекции по номеру индекса, и номер индекса недопустим.

    Это наиболее распространенная причина возникновения ArgumentOutOfRangeException исключения. Как правило, номер индекса является недопустимым по одной из четырех причин:

    1. Коллекция не имеет членов, и код предполагает, что это делает. В следующем примере предпринимается попытка получить первый элемент коллекции, не имеющей элементов:

      using System;
      using System.Collections.Generic;
      
      public class Example
      {
         public static void Main()
         {
            var list = new List<string>();
            Console.WriteLine("Number of items: {0}", list.Count);
            try {
               Console.WriteLine("The first item: '{0}'", list[0]);
            }
            catch (ArgumentOutOfRangeException e) {
               Console.WriteLine(e.Message);
            }
         }
      }
      // The example displays the following output:
      //   Number of items: 0
      //   Index was out of range. Must be non-negative and less than the size of the collection.
      //   Parameter name: index
      
      Imports System.Collections.Generic
      
      Module Example
         Public Sub Main()
            Dim list As New List(Of String)
            Console.WriteLine("Number of items: {0}", list.Count)
            Try
               Console.WriteLine("The first item: '{0}'", list(0))
            Catch e As ArgumentOutOfRangeException
               Console.WriteLine(e.Message)
            End Try
         End Sub
      End Module
      ' The example displays the following output:
      '   Number of items: 0
      '   Index was out of range. Must be non-negative and less than the size of the collection.
      '   Parameter name: index
      

      Чтобы предотвратить исключение, проверьте, больше ли свойство коллекции равно Count нулю, прежде чем пытаться получить какие-либо члены, как это делает в следующем фрагменте кода.

      if (list.Count > 0)
         Console.WriteLine("The first item: '{0}'", list[0]);
      
      If list.Count > 0 Then
         Console.WriteLine("The first item: '{0}'", list(0))
      End If
      
    2. В некоторых случаях исключение может возникнуть из-за попытки добавить элемент в коллекцию с помощью несуществующего индекса, а не путем вызова метода, такого как Add , который существует для этой цели. В следующем примере предпринимается попытка добавить элемент в коллекцию с помощью несуществующего индекса вместо вызова List<T>.Add метода.

      using System;
      using System.Collections.Generic;
      
      public class Example
      {
         public static void Main()
         {
            var numbers = new List<int>();
            numbers.AddRange( new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 } );
      
            var squares = new List<int>();
            for (int ctr = 0; ctr < numbers.Count; ctr++)
               squares[ctr] = (int) Math.Pow(numbers[ctr], 2);
         }
      }
      // The example displays the following output:
      //    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.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
      //       at Example.Main()
      
      Imports System.Collections.Generic
      
      Module Example
         Public Sub Main()
            Dim numbers As New List(Of Integer)
            numbers.AddRange( { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 } )
            
            Dim squares As New List(Of Integer)
            For ctr As Integer = 0 To numbers.Count - 1
               squares(ctr) = CInt(numbers(ctr) ^ 2) 
            Next
         End Sub
      End Module
      ' The example displays the following output:
      '    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.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
      '       at Example.Main()
      

      Следующий фрагмент кода исправляет эту ошибку:

      var squares = new List<int>();
      for (int ctr = 0; ctr < numbers.Count; ctr++)
         squares.Add((int) Math.Pow(numbers[ctr], 2));
      
      Dim squares As New List(Of Integer)
      For ctr As Integer = 0 To numbers.Count - 1
         squares.Add(CInt(numbers(ctr) ^ 2)) 
      Next
      
    3. Предпринимается попытка получить элемент, индекс которого отрицательный. Это обычно происходит из-за того, что в коллекции был выполнен поиск индекса определенного элемента и ошибочно предполагается, что поиск выполнен успешно. В следующем примере вызов List<T>.FindIndex(Predicate<T>) метода не находит строку, равную «Z», поэтому возвращает значение-1. Однако это недопустимое значение индекса.

      using System;
      using System.Collections.Generic;
      
      public class Example
      {
         public static void Main()
         {
            var list = new List<string>();
            list.AddRange( new String[] { "A", "B", "C" } );
            // Get the index of the element whose value is "Z".
            int index = list.FindIndex((new StringSearcher("Z")).FindEquals);
            try {
               Console.WriteLine("Index {0} contains '{1}'", index, list[index]);
            }
            catch (ArgumentOutOfRangeException e) {
               Console.WriteLine(e.Message);
            }
         }
      }
      
      internal class StringSearcher
      {
         string value;
      
         public StringSearcher(string value)
         {
            this.value = value;
         }
      
         public bool FindEquals(string s)
         {
            return s.Equals(value, StringComparison.InvariantCulture);
         }
      }
      // The example displays the following output:
      //   Index was out of range. Must be non-negative and less than the size of the collection.
      //   Parameter name: index
      
      Imports System.Collections.Generic
      
      Module Example
         Public Sub Main()
            Dim list As New List(Of String) 
            list.AddRange( { "A", "B", "C" } )
            ' Get the index of the element whose value is "Z".
            Dim index As Integer = list.FindIndex(AddressOf (New StringSearcher("Z")).FindEquals)
            Try
               Console.WriteLine("Index {0} contains '{1}'", index, list(index)) 
            Catch e As ArgumentOutOfRangeException
               Console.WriteLine(e.Message)
            End Try
         End Sub
      End Module
      
      Friend Class StringSearcher
         Dim value As String
         
         Public Sub New(value As String)
            Me.value = value
         End Sub
         
         Public Function FindEquals(s As String) As Boolean
            Return s.Equals(value, StringComparison.InvariantCulture) 
         End Function
      End Class
      ' The example displays the following output:
      '   Index was out of range. Must be non-negative and less than the size of the collection.
      '   Parameter name: index
      

      Чтобы предотвратить исключение, убедитесь, что поиск прошел успешно, убедившись, что возвращаемый индекс больше или равен нулю, прежде чем пытаться получить элемент из коллекции, как это делает следующий фрагмент кода.

      // Get the index of the element whose value is "Z".
      int index = list.FindIndex((new StringSearcher("Z")).FindEquals);
      if (index >= 0)
         Console.WriteLine("'Z' is found at index {0}", list[index]);
      
      ' Get the index of the element whose value is "Z".
      Dim index As Integer = list.FindIndex(AddressOf (New StringSearcher("Z")).FindEquals)
      If index >= 0 Then
         Console.WriteLine("Index {0} contains '{1}'", index, list(index)) 
      End If
      
    4. Вы пытаетесь получить элемент, индекс которого равен значению Count свойства коллекции, как показано в следующем примере.

      using System;
      using System.Collections.Generic;
      
      public class Example
      {
         public static void Main()
         {
            var list = new List<string>();
            list.AddRange( new String[] { "A", "B", "C" } );
            try {
               // Display the elements in the list by index.
               for (int ctr = 0; ctr <= list.Count; ctr++)
                  Console.WriteLine("Index {0}: {1}", ctr, list[ctr]);
            }
            catch (ArgumentOutOfRangeException e) {
               Console.WriteLine(e.Message);
            }
         }
      }
      // The example displays the following output:
      //   Index 0: A
      //   Index 1: B
      //   Index 2: C
      //   Index was out of range. Must be non-negative and less than the size of the collection.
      //   Parameter name: index
      
      Imports System.Collections.Generic
      
      Module Example
         Public Sub Main()
            Dim list As New List(Of String) 
            list.AddRange( { "A", "B", "C" } )
            Try
               ' Display the elements in the list by index.
               For ctr As Integer = 0 To list.Count
                  Console.WriteLine("Index {0}: {1}", ctr, list(ctr)) 
               Next   
            Catch e As ArgumentOutOfRangeException
               Console.WriteLine(e.Message)
            End Try
         End Sub
      End Module
      ' The example displays the following output:
      '   Index 0: A
      '   Index 1: B
      '   Index 2: C
      '   Index was out of range. Must be non-negative and less than the size of the collection.
      '   Parameter name: index
      

      Поскольку коллекции в .NET используют индексацию, начинающуюся с нуля, первый элемент коллекции находится в индексе 0, а последний элемент — в индексе Count -1. Эту ошибку можно устранить, убедившись, что вы обращаетесь к последнему элементу в индексе Count -1, как показано в следующем коде.

      // Display the elements in the list by index.
      for (int ctr = 0; ctr < list.Count; ctr++)
         Console.WriteLine("Index {0}: {1}", ctr, list[ctr]);
      
      ' Display the elements in the list by index.
      For ctr As Integer = 0 To list.Count - 1 
         Console.WriteLine("Index {0}: {1}", ctr, list(ctr)) 
      Next
      
  • Вы пытаетесь выполнить операцию со строками, вызвав метод обработки строк, а начальный индекс не существует в строке.

    Перегрузки таких методов, как,, String.Compare String.CompareOrdinal ,, String.IndexOf IndexOfAny String.Insert , String.LastIndexOf , String.LastIndexOfAny , Remove или String.Substring , которые позволяют указать начальный индекс операции, требует, чтобы индекс был допустимой позицией в строке. Допустимые индексы находятся в диапазоне от 0 до String.Length -1.

    Существует четыре распространенных причины этого ArgumentOutOfRangeException исключения.

    1. Вы работаете с пустой строкой или String.Empty . Поскольку его String.Length свойство возвращает 0, любая попытка управлять ею по индексу вызывает ArgumentOutOfRangeException исключение. В следующем примере определяется GetFirstCharacter метод, который возвращает первый символ строки. Если строка пуста, то в качестве окончательной строки, передаваемой в метод, метод создает ArgumentOutOfRangeException исключение.

      using System;
      
      public class Example
      {
         public static void Main()
         {
             String[] words = { "the", "today", "tomorrow", " ", "" };
             foreach (var word in words)
                Console.WriteLine("First character of '{0}': '{1}'",
                                  word, GetFirstCharacter(word));
         }
      
         private static char GetFirstCharacter(string s)
         {
            return s[0];
         }
      }
      // The example displays the following output:
      //    First character of //the//: //t//
      //    First character of //today//: //t//
      //    First character of //tomorrow//: //t//
      //    First character of // //: // //
      //
      //    Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
      //       at Example.Main()
      
      Module Example
         Public Sub Main()
             Dim words() As String = { "the", "today", "tomorrow", " ", "" }
             For Each word In words
                Console.WriteLine("First character of '{0}': '{1}'", 
                                  word, GetFirstCharacter(word))
             Next                     
         End Sub
         
         Private Function GetFirstCharacter(s As String) As Char
            Return s(0)
         End Function
      End Module
      ' The example displays the following output:
      '    First character of 'the': 't'
      '    First character of 'today': 't'
      '    First character of 'tomorrow': 't'
      '    First character of ' ': ' '
      '    
      '    Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
      '       at Example.Main()
      

      Исключение можно устранить, проверив, является ли строка String.Length больше нуля, или вызвав IsNullOrEmpty метод, чтобы убедиться, что строка не является null пустой. Следующий фрагмент кода выполняет последнюю функцию. В этом случае, если строка является null или пустой, GetFirstCharacter метод возвращает U + 0000.

      static char GetFirstCharacter(string s)
      {
         if (string.IsNullOrEmpty(s))
            return '\u0000';
         else
            return s[0];
      }
      
      Function GetFirstCharacter(s As String) As Char
         If String.IsNullOrEmpty(s) Then 
            Return ChrW(0)
         Else   
            Return s(0)
         End If   
      End Function
      
    2. Вы работаете со строкой, основанной на положении подстроки в этой строке, и не смогли определить, найдена ли подстрока.

      В следующем примере извлекается второе слово из двух слов. Он создает ArgumentOutOfRangeException исключение, если фраза состоит только из одного слова, и поэтому не содержит пробелов. Это происходит потому, что вызов String.IndexOf(String) метода возвращает значение-1, чтобы указать, что Поиск завершился неудачей, и это недопустимое значение затем передается в String.Substring(Int32) метод.

      using System;
      
      public class Example
      {
         public static void Main()
         {
            String[] phrases = { "ocean blue", "concerned citizen",
                                 "runOnPhrase" };
            foreach (var phrase in phrases)
               Console.WriteLine("Second word is {0}", GetSecondWord(phrase));
         }
      
         static string GetSecondWord(string s)
         {
            int pos = s.IndexOf(" ");
            return s.Substring(pos).Trim();
         }
      }
      // The example displays the following output:
      //    Second word is blue
      //    Second word is citizen
      //
      //    Unhandled Exception: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero.
      //    Parameter name: startIndex
      //       at System.String.Substring(Int32 startIndex, Int32 length)
      //       at Example.GetSecondWord(String s)
      //       at Example.Main()
      
      Module Example
         Public Sub Main()
            Dim phrases() As String = { "ocean blue", "concerned citizen", 
                                        "runOnPhrase" }
            For Each phrase In phrases
               Console.WriteLine("Second word is {0}", GetSecondWord(phrase))
            Next                            
        End Sub
        
        Function GetSecondWord(s As String) As String
           Dim pos As Integer = s.IndexOf(" ")
           Return s.Substring(pos).Trim()
        End Function
      End Module
      ' The example displays the following output:
      '       Second word is blue
      '       Second word is citizen
      '       
      '       Unhandled Exception: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero.
      '       Parameter name: startIndex
      '          at System.String.Substring(Int32 startIndex, Int32 length)
      '          at Example.GetSecondWord(String s)
      '          at Example.Main()
      

      Чтобы исключить исключение, перед вызовом метода обработки строк проверьте значение, возвращаемое методом поиска строки.

      using System;
      
      public class Example
      {
         public static void Main()
         {
            String[] phrases = { "ocean blue", "concerned citizen",
                                 "runOnPhrase" };
            foreach (var phrase in phrases) {
               string word = GetSecondWord(phrase);
               if (! string.IsNullOrEmpty(word))
                  Console.WriteLine("Second word is {0}", word);
            }
         }
      
         static string GetSecondWord(string s)
         {
            int pos = s.IndexOf(" ");
            if (pos >= 0)
               return s.Substring(pos).Trim();
            else
               return string.Empty;
         }
      }
      // The example displays the following output:
      //       Second word is blue
      //       Second word is citizen
      
      Module Example
         Public Sub Main()
            Dim phrases() As String = { "ocean blue", "concerned citizen", 
                                        "runOnPhrase" }
            For Each phrase In phrases
               Dim word As String = GetSecondWord(phrase)
               If Not String.IsNullOrEmpty(word) Then _
                  Console.WriteLine("Second word is {0}", word)
            Next                            
         End Sub
        
         Function GetSecondWord(s As String) As String
            Dim pos As Integer = s.IndexOf(" ")
            If pos >= 0
                Return s.Substring(pos).Trim()
            Else
               Return String.Empty
            End If
        End Function
      End Module
      ' The example displays the following output:
      '       Second word is blue
      '       Second word is citizen
      
    3. Предпринята попытка извлечь подстроку, которая находится за пределами диапазона текущей строки.

      Для методов, которые извлекают подстроки ALL, требуется указать начальную точку подстроки, а для подстрок, которые не продолжаются до конца строки, число символов в подстроке. Обратите внимание, что это не индекс последнего символа в подстроке.

      ArgumentOutOfRangeExceptionВ этом случае в этом случае возникает исключение, поскольку число символов в подстроке неправильно вычислено. При использовании метода поиска, например, String.IndexOf для обнаружения начальной и конечной позиции подстроки:

      • Если символ в конечной позиции, возвращаемый функцией, String.IndexOf должен быть включен в подстроку, то конечная позиция подстроки выдается формулой.

        endIndex - startIndex + 1
        
      • Если символ в конечной позиции, возвращенном, String.IndexOf должен быть исключен из подстроки, конечная позиция подстроки выдается формулой.

        endIndex - startIndex
        

        В следующем примере определяется FindWords метод, который использует String.IndexOfAny(Char[], Int32) метод для определения символов пробела и знаков препинания в строке и возвращает массив, содержащий слова, найденные в строке.

        using System;
        using System.Collections.Generic;
        
        public class Example
        {
           public static void Main()
           {
              string sentence = "This is a simple, short sentence.";
              Console.WriteLine("Words in '{0}':", sentence);
              foreach (var word in FindWords(sentence))
                 Console.WriteLine("   '{0}'", word);
           }
        
           static String[] FindWords(string s)
           {
              int start = 0, end = 0;
              Char[] delimiters = { ' ', '.', ',', ';', ':', '(', ')' };
              var words = new List<string>();
        
              while (end >= 0) {
                 end = s.IndexOfAny(delimiters, start);
                 if (end >= 0) {
                    if (end - start > 0)
                       words.Add(s.Substring(start, end - start));
        
                    start = end + 1;
                 }
                 else {
                    if (start < s.Length - 1)
                       words.Add(s.Substring(start));
                 }
              }
              return words.ToArray();
           }
        }
        // The example displays the following output:
        //       Words in 'This is a simple, short sentence.':
        //          'This'
        //          'is'
        //          'a'
        //          'simple'
        //          'short'
        //          'sentence'
        
        Imports System.Collections.Generic
        
        Module Example
           Public Sub Main()
              Dim sentence As String = "This is a simple, short sentence."
              Console.WriteLine("Words in '{0}':", sentence)
              For Each word In FindWords(sentence)
                 Console.WriteLine("   '{0}'", word)
              Next
           End Sub
           
           Function FindWords(s As String) As String()
              Dim start, ending As Integer
              Dim delimiters() As Char = { " "c, "."c, ","c, ";"c, ":"c,
                                           "("c, ")"c }
              Dim words As New List(Of String)()
        
              Do While ending >= 0
                 ending = s.IndexOfAny(delimiters, start)
                 If ending >= 0
                    If ending - start > 0 Then
                       words.Add(s.Substring(start, ending - start)) 
                    End If
                    start = ending + 1
                 Else
                    If start < s.Length - 1 Then
                       words.Add(s.Substring(start))
                    End If      
                 End If
              Loop    
              Return words.ToArray()                         
           End Function
        End Module
        ' The example displays the following output:
        '       Words in 'This is a simple, short sentence.':
        '          'This'
        '          'is'
        '          'a'
        '          'simple'
        '          'short'
        '          'sentence'
        
  • Вы передали отрицательное число в метод с аргументом, который требует только положительные числа и ноль, или вы передали отрицательное число или нуль в метод с аргументом, который требует только положительных чисел.

    Например, Array.CreateInstance(Type, Int32, Int32, Int32) метод требует указать количество элементов в каждом измерении двумерного массива; допустимые значения для каждого измерения могут находиться в диапазоне от 0 до Int32.MaxValue . Но поскольку аргумент Dimension в следующем примере имеет отрицательное значение, метод создает ArgumentOutOfRangeException исключение.

    using System;
    
    public class Example
    {
       public static void Main()
       {
          int dimension1 = 10;
          int dimension2 = -1;
          try {
             Array arr = Array.CreateInstance(typeof(string),
                                              dimension1, dimension2);
          }
          catch (ArgumentOutOfRangeException e) {
             if (e.ActualValue != null)
                Console.WriteLine("{0} is an invalid value for {1}: ", e.ActualValue, e.ParamName);
             Console.WriteLine(e.Message);
          }
       }
    }
    // The example displays the following output:
    //     Non-negative number required.
    //     Parameter name: length2
    
    Module Example
       Public Sub Main()
          Dim dimension1 As Integer = 10
          Dim dimension2 As Integer = -1
          Try
             Dim arr AS Array = Array.CreateInstance(GetType(String), 
                                                     dimension1, dimension2)
          Catch e As ArgumentOutOfRangeException
             If e.ActualValue IsNot Nothing Then
                Console.WriteLine("{0} is an invalid value for {1}: ", 
                                  e.ActualValue, e.ParamName)
             End If                     
             Console.WriteLine(e.Message)
          End Try
       End Sub
    End Module
    ' The example displays the following output:
    '     Non-negative number required.
    '     Parameter name: length2
    

    Чтобы исправить ошибку, убедитесь, что значение недопустимого аргумента не отрицательное. Это можно сделать, указав допустимое значение, как показано в следующем фрагменте кода.

    int dimension1 = 10;
    int dimension2 = 10;
    Array arr = Array.CreateInstance(typeof(string),
                                     dimension1, dimension2);
    
    Dim dimension1 As Integer = 10
    Dim dimension2 As Integer = 10
    Dim arr As Array = Array.CreateInstance(GetType(String), 
                                            dimension1, dimension2)
    

    Вы также можете проверить входные данные и, если они недопустимы, выполните некоторые действия. В следующем фрагменте кода выводится сообщение об ошибке вместо вызова метода.

    if (dimension1 < 0 || dimension2 < 0) {
       Console.WriteLine("Unable to create the array.");
       Console.WriteLine("Specify non-negative values for the two dimensions.");
    }
    else {
       arr = Array.CreateInstance(typeof(string),
                                  dimension1, dimension2);
    }
    
    If dimension1 < 0 OrElse dimension2 < 0 Then
       Console.WriteLine("Unable to create the array.")
       Console.WriteLine("Specify non-negative values for the two dimensions.")
    Else
       arr = Array.CreateInstance(GetType(String), 
                                  dimension1, dimension2)   
    End If
    
  • Состояние гонки существует в приложении, которое является многопоточным или имеет задачи, выполняемые асинхронно и выполняющие обновление массива или коллекции.

    В следующем примере объект используется List<T> для заполнения коллекции Continent объектов. Он создает исключение, ArgumentOutOfRangeException Если в примере предпринимается попытка отобразить семь элементов в коллекции до полного заполнения коллекции.

    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    public class Continent
    {
       public string Name { get; set; }
       public int Population { get; set; }
       public Decimal Area { get; set; }
    }
    
    public class Example
    {
       static List<Continent> continents = new List<Continent>();
       static string msg;
    
       public static void Main()
       {
          String[] names = { "Africa", "Antarctica", "Asia",
                             "Australia", "Europe", "North America",
                             "South America" };
          // Populate the list.
          foreach (var name in names) {
             var th = new Thread(PopulateContinents);
             th.Start(name);
          }
          Console.WriteLine(msg);
          Console.WriteLine();
    
          // Display the list.
          for (int ctr = 0; ctr < names.Length; ctr++) {
             var continent = continents[ctr];
             Console.WriteLine("{0}: Area: {1}, Population {2}",
                               continent.Name, continent.Population,
                               continent.Area);
          }
       }
    
       private static void PopulateContinents(Object obj)
       {
          string name = obj.ToString();
          msg += string.Format("Adding '{0}' to the list.\n", name);
          var continent = new Continent();
          continent.Name = name;
          // Sleep to simulate retrieving remaining data.
          Thread.Sleep(50);
          continents.Add(continent);
       }
    }
    // The example displays output like the following:
    //    Adding //Africa// to the list.
    //    Adding //Antarctica// to the list.
    //    Adding //Asia// to the list.
    //    Adding //Australia// to the list.
    //    Adding //Europe// to the list.
    //    Adding //North America// to the list.
    //    Adding //South America// to the list.
    //
    //
    //
    //    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.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
    //       at Example.Main()
    
    Imports System.Collections.Generic
    Imports System.Threading
    
    Public Class Continent
       Public Property Name As String
       Public Property Population As Integer
       Public Property Area As Decimal  
    End Class
    
    Module Example
       Dim continents As New List(Of Continent)
       Dim msg As String 
          
       Public Sub Main()
          Dim names() As String = { "Africa", "Antarctica", "Asia", 
                                         "Australia", "Europe", "North America",
                                         "South America" }
          ' Populate the list.
          For Each name In names
             Dim th As New Thread(AddressOf PopulateContinents)
             th.Start(name)
          Next              
          Console.WriteLine(msg)
          Console.WriteLine()
    
          ' Display the list.
          For ctr As Integer = 0 To names.Length - 1
             Dim continent = continents(ctr)
             Console.WriteLine("{0}: Area: {1}, Population {2}", 
                               continent.Name, continent.Population,
                               continent.Area)
          Next
       End Sub
       
       Private Sub PopulateContinents(obj As Object)
          Dim name As String = obj.ToString()
          msg += String.Format("Adding '{0}' to the list.{1}", name, vbCrLf)
          Dim continent As New Continent()
          continent.Name = name
          ' Sleep to simulate retrieving remaining data.
          Thread.Sleep(50)
          continents.Add(continent)
       End Sub
    End Module
    ' The example displays output like the following:
    '    Adding 'Africa' to the list.
    '    Adding 'Antarctica' to the list.
    '    Adding 'Asia' to the list.
    '    Adding 'Australia' to the list.
    '    Adding 'Europe' to the list.
    '    Adding 'North America' to the list.
    '    Adding 'South America' to the list.
    '    
    '    
    '    
    '    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.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
    '       at Example.Main()
    

    В этом случае доступ к двум ресурсам осуществляется из нескольких потоков:

    • Коллекция continents. Его List<T>.Add метод вызывается из нескольких потоков. Кроме того, основной или основной поток предполагает, что коллекция полностью заполняется семью элементами при итерации элементов.

    • msgСтрока, которая объединяется из нескольких потоков.

    Чтобы исправить ошибку, убедитесь, что доступ к общему состоянию осуществляется потокобезопасным способом, как показано ниже.

    • Если в приложении используется объект массива или коллекции, рассмотрите возможность использования классической коллекции, такой как типы в System.Collections.Concurrent пространстве имен или System.Collections.Immutable выпуске по внештатному каналу.

    • Убедитесь, что доступ к общему состоянию (т. е. к ресурсам, доступным нескольким потокам) осуществляется потокобезопасным способом, так что только один поток в каждый момент времени имеет монопольный доступ к ресурсам. CountdownEvent Interlocked Monitor Mutex Для синхронизации доступа к ресурсам доступны большое количество классов, например,, и. Дополнительные сведения см. в разделе многопоточность. Кроме того, языковая поддержка доступна с помощью оператора Lock в C# и конструкции SyncLock в Visual Basic.

    В следующем примере рассматриваются ArgumentOutOfRangeException и другие проблемы из предыдущего примера. Он заменяет List<T> объект ConcurrentBag<T> объектом, чтобы обеспечить потокобезопасность доступа к коллекции, использует объект, CountdownEvent чтобы обеспечить продолжение потока приложения только после выполнения других потоков, и использует блокировку, чтобы гарантировать, что только один поток может получить доступ к msg переменной за раз.

    using System;
    using System.Collections.Concurrent;
    using System.Threading;
    
    public class Continent
    {
       public string Name { get; set; }
       public int Population { get; set; }
       public Decimal Area { get; set; }
    }
    
    public class Example
    {
       static ConcurrentBag<Continent> continents = new ConcurrentBag<Continent>();
       static CountdownEvent gate;
       static string msg = string.Empty;
    
       public static void Main()
       {
          String[] names = { "Africa", "Antarctica", "Asia",
                             "Australia", "Europe", "North America",
                             "South America" };
          gate = new CountdownEvent(names.Length);
    
          // Populate the list.
          foreach (var name in names) {
             var th = new Thread(PopulateContinents);
             th.Start(name);
          }
    
          // Display the list.
          gate.Wait();
          Console.WriteLine(msg);
          Console.WriteLine();
    
          var arr = continents.ToArray();
          for (int ctr = 0; ctr < names.Length; ctr++) {
             var continent = arr[ctr];
             Console.WriteLine("{0}: Area: {1}, Population {2}",
                               continent.Name, continent.Population,
                               continent.Area);
          }
       }
    
       private static void PopulateContinents(Object obj)
       {
          string name = obj.ToString();
          lock(msg) {
             msg += string.Format("Adding '{0}' to the list.\n", name);
          }
          var continent = new Continent();
          continent.Name = name;
          // Sleep to simulate retrieving remaining data.
          Thread.Sleep(25);
          continents.Add(continent);
          gate.Signal();
       }
    }
    // The example displays output like the following:
    //       Adding 'Africa' to the list.
    //       Adding 'Antarctica' to the list.
    //       Adding 'Asia' to the list.
    //       Adding 'Australia' to the list.
    //       Adding 'Europe' to the list.
    //       Adding 'North America' to the list.
    //       Adding 'South America' to the list.
    //
    //
    //       Africa: Area: 0, Population 0
    //       Antarctica: Area: 0, Population 0
    //       Asia: Area: 0, Population 0
    //       Australia: Area: 0, Population 0
    //       Europe: Area: 0, Population 0
    //       North America: Area: 0, Population 0
    //       South America: Area: 0, Population 0
    
    Imports System.Collections.Concurrent
    Imports System.Threading
    
    Public Class Continent
       Public Property Name As String
       Public Property Population As Integer
       Public Property Area As Decimal  
    End Class
    
    Module Example
       Dim continents As New ConcurrentBag(Of Continent)
       Dim gate As CountdownEvent
       Dim msg As String = String.Empty
          
       Public Sub Main()
          Dim names() As String = { "Africa", "Antarctica", "Asia", 
                                    "Australia", "Europe", "North America",
                                    "South America" }
          gate = new CountdownEvent(names.Length)
          
          ' Populate the list.
          For Each name In names
             Dim th As New Thread(AddressOf PopulateContinents)
             th.Start(name)
          Next              
    
          ' Display the list.
          gate.Wait()
          Console.WriteLine(msg)
          Console.WriteLine()
    
          For ctr As Integer = 0 To names.Length - 1
             Dim continent = continents(ctr)
             Console.WriteLine("{0}: Area: {1}, Population {2}", 
                               continent.Name, continent.Population,
                               continent.Area)
          Next
       End Sub
       
       Private Sub PopulateContinents(obj As Object)
          Dim name As String = obj.ToString()
          SyncLock msg 
             msg += String.Format("Adding '{0}' to the list.{1}", name, vbCrLf)
          End SyncLock
          Dim continent As New Continent()
          continent.Name = name
          ' Sleep to simulate retrieving remaining data.
          Thread.Sleep(25)
          continents.Add(continent)
          gate.Signal()
       End Sub
    End Module
    ' The example displays output like the following:
    '    Adding 'Africa' to the list.
    '    Adding 'Antarctica' to the list.
    '    Adding 'Asia' to the list.
    '    Adding 'Australia' to the list.
    '    Adding 'Europe' to the list.
    '    Adding 'North America' to the list.
    '    Adding 'South America' to the list.
    '    
    '    
    '    Africa: Area: 0, Population 0
    '    Antarctica: Area: 0, Population 0
    '    Asia: Area: 0, Population 0
    '    Australia: Area: 0, Population 0
    '    Europe: Area: 0, Population 0
    '    North America: Area: 0, Population 0
    '    South America: Area: 0, Population 0
    

ArgumentOutOfRangeException использует COR_E_ARGUMENTOUTOFRANGE HRESULT, имеющий значение 0x80131502.

Список начальных значений свойств для экземпляра ArgumentOutOfRangeException, см. в разделе ArgumentOutOfRangeException конструкторы.

Конструкторы

ArgumentOutOfRangeException()

Инициализирует новый экземпляр класса ArgumentOutOfRangeException.

ArgumentOutOfRangeException(SerializationInfo, StreamingContext)

Инициализирует новый экземпляр класса ArgumentOutOfRangeException с сериализованными данными.

ArgumentOutOfRangeException(String)

Инициализирует новый экземпляр класса ArgumentOutOfRangeException именем параметра, вызвавшего исключение.

ArgumentOutOfRangeException(String, Exception)

Инициализирует новый экземпляр класса ArgumentOutOfRangeException с заданным сообщением об ошибке и ссылкой на внутреннее исключение, которое стало причиной данного исключения.

ArgumentOutOfRangeException(String, Object, String)

Инициализирует новый экземпляр класса ArgumentOutOfRangeException с именем параметра, значением аргумента и указанным сообщением об ошибке.

ArgumentOutOfRangeException(String, String)

Инициализирует новый экземпляр класса ArgumentOutOfRangeException с именем параметра, ставшего причиной этого исключения, и указанным сообщением об ошибке.

Свойства

ActualValue

Возвращает значение аргумента, вызвавшего это исключение.

Data

Возвращает коллекцию пар «ключ-значение», предоставляющую дополнительные сведения об исключении.

(Унаследовано от Exception)
HelpLink

Получает или задает ссылку на файл справки, связанный с этим исключением.

(Унаследовано от Exception)
HResult

Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.

(Унаследовано от Exception)
InnerException

Возвращает экземпляр класса Exception, который вызвал текущее исключение.

(Унаследовано от Exception)
Message

Возвращает сообщение об ошибке и строковое представление недопустимого значения аргумента или только сообщение об ошибке, если значение аргумента равно null.

ParamName

Возвращает имя параметра, ставшего причиной этого исключения.

(Унаследовано от ArgumentException)
Source

Возвращает или задает имя приложения или объекта, вызывавшего ошибку.

(Унаследовано от Exception)
StackTrace

Получает строковое представление непосредственных кадров в стеке вызова.

(Унаследовано от Exception)
TargetSite

Возвращает метод, создавший текущее исключение.

(Унаследовано от Exception)

Методы

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
GetBaseException()

При переопределении в производном классе возвращает исключение Exception, которое является первопричиной одного или нескольких последующих исключений.

(Унаследовано от Exception)
GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetObjectData(SerializationInfo, StreamingContext)

Задает в объекте SerializationInfo недопустимое значение аргумента и дополнительные сведения об исключении.

GetObjectData(SerializationInfo, StreamingContext)

Задает объекту SerializationInfo имя параметра и дополнительную информацию об исключении.

(Унаследовано от ArgumentException)
GetType()

Возвращает тип среды выполнения текущего экземпляра.

(Унаследовано от Exception)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
ToString()

Создает и возвращает строковое представление текущего исключения.

(Унаследовано от Exception)

События

SerializeObjectState
Является устаревшей.

Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении.

(Унаследовано от Exception)

Применяется к

См. также раздел