共用方式為


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;
using static System.Console;

public class Program
{
    public static void Main(string[] args)
    {
        try
        {
            var guest1 = new Guest("Ben", "Miller", 17);
            WriteLine(guest1.GuestInfo);
        }
        catch (ArgumentOutOfRangeException argumentOutOfRangeException)
        {
            WriteLine($"Error: {argumentOutOfRangeException.Message}");
        }
    }
}

class Guest
{
    private const int minimumRequiredAge = 21;

    private string firstName;
    private string lastName;
    private int age;

    public Guest(string firstName, string lastName, int age)
    {
        if (age < minimumRequiredAge)
            throw new ArgumentOutOfRangeException(nameof(age), $"All guests must be {minimumRequiredAge}-years-old or older.");

        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public string GuestInfo => $"{firstName} {lastName}, {age}";
}
open System

type Guest(fName: string, lName: string, age: int) =
    let minimumRequiredAge = 21

    do if age < minimumRequiredAge then 
        raise (ArgumentOutOfRangeException(nameof age, $"All guests must be {minimumRequiredAge}-years-old or older."))

    member _.FirstName = fName
    member _.LastName = lName
    member _.GuestInfo() = $"{fName} {lName}, {age}"

try
    let guest1 = Guest("Ben", "Miller", 17);
    printfn $"{guest1.GuestInfo()}"
with
| :? ArgumentOutOfRangeException as e ->
    printfn $"Error: {e.Message}"
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 Example4
      {
         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
      
      open System
      
      
      let list = ResizeArray<string>()
      printfn $"Number of items: {list.Count}"
      try
          printfn $"The first item: '{list[0]}'"
      with 
      | :? ArgumentOutOfRangeException as e ->
          printfn $"{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 '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
          printfn $"The first item: '{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 Example13
      {
         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()
      
      let numbers = ResizeArray<int>()
      numbers.AddRange [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 20 ]
      
      let squares = ResizeArray<int>()
      for  ctr = 0 to numbers.Count - 1 do
          squares[ctr] <- int (float 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 'index')
      //       at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
      //       at <StartupCode$argumentoutofrangeexception>.$NoElements.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));
      
      let squares = ResizeArray<int>()
      for ctr = 0 to numbers.Count - 1 do
          squares.Add(int (float 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
      
      open System
      
      module StringSearcher =
          let findEquals (s: string) value =
              s.Equals(value, StringComparison.InvariantCulture)
      
      let list = ResizeArray<string>()
      list.AddRange [ "A"; "B"; "C" ]
      // Get the index of the element whose value is "Z".
      let index = list.FindIndex(StringSearcher.findEquals "Z")
      try 
          printfn $"Index {index} contains '{list[index]}'"
      with 
      | :? ArgumentOutOfRangeException as e ->
          printfn $"{e.Message}" 
      
      // The example displays the following output:
      //   Index was out of range. Must be non-negative and less than the size of the collection. (Parameter '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".
      let index = list.FindIndex(StringSearcher.findEquals "Z")
      if index >= 0 then
          printfn $"'Z' is found at index {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 Example8
      {
         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
      
      open System
      
      let list = ResizeArray<string>()
      list.AddRange [ "A"; "B"; "C" ] 
      try
          // Display the elements in the list by index.
          for i = 0 to list.Count do
              printfn $"Index {i}: {list[i]}"
      with 
      | :? ArgumentOutOfRangeException as e ->
          printfn $"{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 '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 i = 0 to list.Count - 1 do
          printfn $"Index {i}: {list[i]}"
      
      ' 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.CompareOrdinalIndexOfAnyString.IndexOfRemoveString.InsertString.LastIndexOfString.LastIndexOfAnyString.Substring ,允許你指定操作的起始索引,這些方法要求該索引必須是字串中的有效位置。 有效索引範圍為 0 到 String.Length - 1。

    ArgumentOutOfRangeException 例外常見原因有四:

    1. 你正在處理一個空字串,或 String.Empty。 由於其 String.Length 屬性回傳 0,任何嘗試用索引操作都會拋 ArgumentOutOfRangeException 出例外。 以下範例定義了一種 GetFirstCharacter 回傳字串第一個字元的方法。 如果字串是空的,就像最後傳給方法的字串一樣,方法會拋 ArgumentOutOfRangeException 出例外。

      using System;
      
      public class Example1
      {
          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()
      
      open System
      
      let getFirstCharacter (s: string) = s[0]
      
      let words = [ "the"; "today"; "tomorrow"; " "; "" ]
      for word in words do
          printfn $"First character of '{word}': '{getFirstCharacter word}'"
      
      // 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 <StartupCode$argumentoutofrangeexception>.$EmptyString1.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 空的,來消除例外。 以下程式碼片段就是後者。 此時若字串為 nullGetFirstCharacter ,方法回傳 U+0000。

      static char GetFirstCharacter(string s)
      {
          if (string.IsNullOrEmpty(s))
              return '\u0000';
          else
              return s[0];
      }
      
      let getFirstCharacter (s: string) =
         if String.IsNullOrEmpty s then
            '\u0000'
         else
            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 Example17
      {
         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 Example17.GetSecondWord(String s)
      //       at Example17.Main()
      
      let getSecondWord (s: string) =
          let pos = s.IndexOf " "
          s.Substring(pos).Trim()
      
      let phrases = [ "ocean blue"; "concerned citizen"; "runOnPhrase" ]
      for phrase in phrases do
          printfn $"Second word is {getSecondWord phrase}"
      
      // 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 'startIndex')
      //       at System.String.Substring(Int32 startIndex, Int32 length)
      //       at System.String.Substring(Int32 startIndex)
      //       at NoFind1.getSecondWord(String s)
      //       at <StartupCode$argumentoutofrangeexception>.$NoFind1.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 Example18
      {
         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
      
      open System
      
      let getSecondWord (s: string) =
          let pos = s.IndexOf " "
          if pos >= 0 then
              s.Substring(pos).Trim()
          else 
              String.Empty
      
      let phrases = [ "ocean blue"; "concerned citizen"; "runOnPhrase" ]
      for phrase in phrases do
          let word = getSecondWord phrase
          if not (String.IsNullOrEmpty word) then
              printfn $"Second word is {word}"
      
      // 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. 你嘗試提取一個超出當前字串範圍的子字串。

      所有提取子字串的方法都要求你指定子字串的起始位置,對於不延伸到字串末尾的子字串,則指定該子字串的字元數。 請注意,這不是子字串最後一個字元的 索引

      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 Example19
        {
           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'
        
        
        let findWords (s: string) =
            let mutable start, end' = 0, 0
            let delimiters = [| ' '; '.'; ','; ';'; ':'; '('; ')' |]
            let words = ResizeArray<string>()
            while end' >= 0 do
                end' <- s.IndexOfAny(delimiters, start)
                if end' >= 0 then
                    if end' - start > 0 then
                        words.Add(s.Substring(start, end' - start))
                    start <- end' + 1
                elif start < s.Length - 1 then
                    words.Add(s.Substring start)
            words.ToArray()
        
        let sentence = "This is a simple, short sentence."
        printfn $"Words in '{sentence}':"
        for word in findWords sentence do
            printfn $"   '{word}'"
        
        // 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。 但由於以下範例中的維度參數為負值,該方法會拋 ArgumentOutOfRangeException 出例外。

    using System;
    
    public class Example01
    {
        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
    
    open System
    
    let dimension1 = 10
    let dimension2 = -1
    try
        let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2)
        printfn "%A" arr
    with 
    | :? ArgumentOutOfRangeException as e ->
        if not (isNull e.ActualValue) then
            printfn $"{e.ActualValue} is an invalid value for {e.ParamName}: "
        printfn $"{e.Message}"
    
    // The example displays the following output:
    //     Non-negative number required. (Parameter '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);
    
    let dimension1 = 10
    let dimension2 = 10
    let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2)
    printfn "%A" arr
    
    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 || dimension2 < 0 then
        printfn "Unable to create the array."
        printfn "Specify non-negative values for the two dimensions."
    else
        let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2)
        printfn "%A" arr
    
    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 if,範例嘗試在集合尚未完全填滿前顯示該集合中的七個項目。

    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 Example11
    {
       static List<Continent> continents = new List<Continent>();
       static string? s_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(s_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();
          s_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()
    
    open System.Threading
    
    type Continent =
        { Name: string
          Population: int
          Area: decimal }
    
    let continents = ResizeArray<Continent>()
    let mutable msg = ""
    
    let names = 
        [ "Africa"; "Antarctica"; "Asia"
          "Australia"; "Europe"; "North America"
          "South America" ]
    
    let populateContinents obj = 
        let name = string obj
        msg <- msg + $"Adding '{name}' to the list.\n"
        // Sleep to simulate retrieving data.
        Thread.Sleep 50
        let continent = 
            { Name = name
              Population = 0
              Area = 0M }
        continents.Add continent
          
    // Populate the list.
    for name in names do
        let th = Thread(ParameterizedThreadStart populateContinents)
        th.Start name
          
    printfn $"{msg}\n"
    
    // Display the list.
    for i = 0 to names.Length - 1 do
        let continent = continents[i]
        printfn $"{continent.Name}: Area: {continent.Population}, Population {continent.Area}"
    
    // The example displays output like the following:
    //    Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
    //       at System.Collections.Generic.List`1.get_Item(Int32 index)
    //       at <StartupCode$argumentoutofrangeexception>.$Race1.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()
    

    此時,兩個資源會從多個執行緒存取:

    • 收藏。continentsList<T>.Add 方法可從多個執行緒中呼叫。 此外,主線程在迭代成員時假設集合已完整填充七個元素。

    • msg 串是由多個執行緒串接而成。

    要修正錯誤,請確保共享狀態是以執行緒安全的方式存取,如下。

    以下範例將 ArgumentOutOfRangeException 針對上述及其他問題進行說明。 它用物件替換List<T>ConcurrentBag<T>物件以確保存取集合是執行緒安全的,使用CountdownEvent物件確保應用程式執行緒只有在其他執行緒執行後才繼續,並使用鎖確保一次只有一個執行緒能存取變msg數。

    using System;
    using System.Collections.Concurrent;
    using System.Threading;
    
    public class ContinentD
    {
       public string? Name { get; set; }
       public int Population { get; set; }
       public Decimal Area { get; set; }
    }
    
    public class Example12
    {
       static ConcurrentBag<ContinentD> ContinentDs = new ConcurrentBag<ContinentD>();
       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(PopulateContinentDs);
             th.Start(name);
          }
    
          // Display the list.
          gate.Wait();
          Console.WriteLine(msg);
          Console.WriteLine();
    
          var arr = ContinentDs.ToArray();
          for (int ctr = 0; ctr < names.Length; ctr++) {
             var ContinentD = arr[ctr];
             Console.WriteLine("{0}: Area: {1}, Population {2}",
                               ContinentD.Name, ContinentD.Population,
                               ContinentD.Area);
          }
       }
    
       private static void PopulateContinentDs(Object? obj)
       {
          string? name = obj?.ToString();
          lock(msg) {
             msg += string.Format("Adding '{0}' to the list.\n", name);
          }
          var ContinentD = new ContinentD();
          ContinentD.Name = name;
          // Sleep to simulate retrieving remaining data.
          Thread.Sleep(25);
          ContinentDs.Add(ContinentD);
          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
    
    open System.Collections.Concurrent
    open System.Threading
    
    type Continent =
        { Name: string
          Population: int
          Area: decimal }
    
    let continents = ConcurrentBag<Continent>();
    let mutable msg = ""
    
    let names = 
        [ "Africa"; "Antarctica"; "Asia"
          "Australia"; "Europe"; "North America"
          "South America" ]
    
    let gate = new CountdownEvent(names.Length)
    
    let populateContinents obj = 
        let name = string obj
        lock msg (fun () -> 
            msg <- msg + $"Adding '{name}' to the list.\n" )
    
        // Sleep to simulate retrieving remaining data.
        let continent = 
            { Name = name
              Population = 0
              Area = 0M }
        Thread.Sleep 25
        continents.Add continent
        gate.Signal() |> ignore
    
    // Populate the list.
    for name in names do
        let th = Thread(ParameterizedThreadStart populateContinents)
        th.Start name
    
    // Display the list.
    gate.Wait();
    printfn $"{msg}\n"
    
    let arr = continents.ToArray();
    for i = 0 to names.Length - 1 do
        let continent = arr[i]
        printfn $"{continent.Name}: Area: {continent.Population}, Population {continent.Area}"
    
    // 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 使用 HRESULT COR_E_ARGUMENTOUTOFRANGE,其值為 0x80131502。

如需查看 ArgumentOutOfRangeException 實例的初始屬性值列表,請參閱 ArgumentOutOfRangeException 的建構子。

建構函式

名稱 Description
ArgumentOutOfRangeException()

初始化 ArgumentOutOfRangeException 類別的新執行個體。

ArgumentOutOfRangeException(SerializationInfo, StreamingContext)
已淘汰.

使用串行化數據,初始化 ArgumentOutOfRangeException 類別的新實例。

ArgumentOutOfRangeException(String, Exception)

初始化一個新的類別實例 ArgumentOutOfRangeException ,並以指定的錯誤訊息及導致該例外的例外。

ArgumentOutOfRangeException(String, Object, String)

初始化一個新的類別實例 ArgumentOutOfRangeException ,包含參數名稱、參數值及指定錯誤訊息。

ArgumentOutOfRangeException(String, String)

初始化一個新的類別實例 ArgumentOutOfRangeException ,並以引起此例外的參數名稱及指定的錯誤訊息。

ArgumentOutOfRangeException(String)

初始化一個新的類別實例 ArgumentOutOfRangeException ,並以引起此例外的參數名稱。

屬性

名稱 Description
ActualValue

取得導致此例外的參數值。

Data

取得一組鍵值對,提供關於例外的額外使用者定義資訊。

(繼承來源 Exception)
HelpLink

取得或設定與此例外相關的說明檔案連結。

(繼承來源 Exception)
HResult

取得或設定 HRESULT,一個編碼的數值,指派給特定例外。

(繼承來源 Exception)
InnerException

會取得 Exception 造成目前例外的實例。

(繼承來源 Exception)
Message

取得錯誤訊息及無效參數值的字串表示,或僅在參數值為空時取得錯誤訊息。

ParamName

取得導致此例外的參數名稱。

(繼承來源 ArgumentException)
Source

取得或設定造成錯誤之應用程式或物件的名稱。

(繼承來源 Exception)
StackTrace

會取得呼叫堆疊上即時框架的字串表示。

(繼承來源 Exception)
TargetSite

會取得拋出當前例外的方法。

(繼承來源 Exception)

方法

名稱 Description
Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetBaseException()

當在派生類別中被覆寫時,回傳 Exception 是一個或多個後續例外的根因。

(繼承來源 Exception)
GetHashCode()

做為預設哈希函式。

(繼承來源 Object)
GetObjectData(SerializationInfo, StreamingContext)
已淘汰.

將物件設定 SerializationInfo 為無效的參數值及額外的例外資訊。

GetType()

取得目前實例的執行時型態。

(繼承來源 Exception)
MemberwiseClone()

建立目前 Object的淺層複本。

(繼承來源 Object)
ThrowIfEqual<T>(T, T, String)

拋出 ArgumentOutOfRangeExceptionvalue 等於 other

ThrowIfGreaterThan<T>(T, T, String)

若 大於 other,則拋出 。ArgumentOutOfRangeExceptionvalue

ThrowIfGreaterThanOrEqual<T>(T, T, String)

valueother於等於 ,則拋出 。ArgumentOutOfRangeException

ThrowIfLessThan<T>(T, T, String)

ArgumentOutOfRangeException 出 若 value 小於 other

ThrowIfLessThanOrEqual<T>(T, T, String)

若 小於等other於 ,則拋出 。ArgumentOutOfRangeExceptionvalue

ThrowIfNegative<T>(T, String)

擲出 ArgumentOutOfRangeException 一個如果 value 是負的。

ThrowIfNegativeOrZero<T>(T, String)

擲出一個 ArgumentOutOfRangeException 是否 value 為負或為零的條件。

ThrowIfNotEqual<T>(T, T, String)

拋出 若 ArgumentOutOfRangeExceptionvalue 不等於 other

ThrowIfZero<T>(T, String)

拋出一個 ArgumentOutOfRangeException 如果 value 為零。

ToString()

建立並回傳當前例外的字串表示。

(繼承來源 Exception)

事件

名稱 Description
SerializeObjectState
已淘汰.

當例外被序列化以建立包含該例外序列化資料的例外狀態物件時,會發生這種情況。

(繼承來源 Exception)

適用於

另請參閱