ArgumentOutOfRangeException Klasa
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Wyjątek zgłaszany, gdy wartość argumentu znajduje się poza dopuszczalnym zakresem wartości zdefiniowanym przez wywołaną metodę.
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
- Dziedziczenie
- Dziedziczenie
- Atrybuty
- Implementuje
Przykłady
W poniższym przykładzie zdefiniowano klasę zawierającą informacje o zaproszonym gościu. Jeśli gość jest młodszy niż 21, ArgumentOutOfRangeException zgłaszany jest wyjątek.
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
Uwagi
Wyjątek ArgumentOutOfRangeException jest zgłaszany, gdy wywoływana jest metoda, a co najmniej jeden z argumentów przekazanych do metody nie null
jest i zawiera nieprawidłową wartość, która nie jest elementem członkowskim zestawu wartości oczekiwanych dla argumentu. Właściwość ParamName identyfikuje nieprawidłowy argument, a ActualValue właściwość , jeśli wartość jest obecna, identyfikuje nieprawidłową wartość.
ArgumentOutOfRangeException Zazwyczaj wynik błędu dewelopera. Zamiast obsługiwać wyjątek w try
/catch
bloku, należy wyeliminować przyczynę wyjątku lub, jeśli argument jest zwracany przez wywołanie metody lub dane wejściowe przez użytkownika przed przekazaniem do metody, która zgłasza wyjątek, należy zweryfikować argumenty przed przekazaniem ich do metody.
ArgumentOutOfRangeException jest szeroko używany przez:
Klasy w System.Collections przestrzeniach nazw i System.IO .
Klasa Array .
Metody manipulowania String ciągami w klasie.
Warunki, w których ArgumentOutOfRangeException zgłaszany jest wyjątek, obejmują następujące elementy:
Pobierasz element członkowski kolekcji według jego numeru indeksu, a numer indeksu jest nieprawidłowy.
Jest to najczęstsza przyczyna ArgumentOutOfRangeException wyjątku. Zazwyczaj numer indeksu jest nieprawidłowy z jednego z czterech powodów:
Kolekcja nie ma elementów członkowskich, a kod zakłada, że to robi. Poniższy przykład próbuje pobrać pierwszy element kolekcji, który nie ma elementów:
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
Aby zapobiec wyjątkowi, sprawdź, czy właściwość kolekcji
Count
jest większa niż zero przed podjęciem próby pobrania wszystkich elementów członkowskich, jak wykonuje poniższy fragment kodu.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
W niektórych przypadkach może wystąpić wyjątek, ponieważ próbujesz dodać element członkowski do kolekcji przy użyciu indeksu, który nie istnieje, a nie przez wywołanie metody, takiej jak
Add
, która istnieje w tym celu. Poniższy przykład próbuje dodać element do kolekcji przy użyciu nieistniejącego indeksu List<T>.Add , a nie wywołania metody.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()
Następujący fragment kodu poprawia ten błąd:
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
Próbujesz pobrać element, którego indeks jest ujemny. Zwykle dzieje się tak, ponieważ przeszukiwano kolekcję dla indeksu określonego elementu i błędnie zakładano, że wyszukiwanie zakończyło się pomyślnie. W poniższym przykładzie wywołanie List<T>.FindIndex(Predicate<T>) metody nie może odnaleźć ciągu równego "Z", dlatego zwraca wartość -1. Jest to jednak nieprawidłowa wartość indeksu.
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
Aby zapobiec wyjątkowi, sprawdź, czy wyszukiwanie zakończyło się pomyślnie, upewniając się, że zwrócony indeks jest większy niż lub równy zero przed podjęciem próby pobrania elementu z kolekcji, jak wykonuje poniższy fragment kodu.
// 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
Próbujesz pobrać element, którego indeks jest równy wartości właściwości kolekcji
Count
, jak pokazano w poniższym przykładzie.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
Ponieważ kolekcje na platformie .NET używają indeksowania opartego na zera, pierwszym elementem kolekcji jest indeks 0, a ostatni element znajduje się w indeksie
Count
— 1. Błąd można wyeliminować, upewniając się, że uzyskujesz dostęp do ostatniego elementu w indeksieCount
— 1, jak wykonuje poniższy kod.// 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
Próbujesz wykonać operację ciągu, wywołując metodę manipulowania ciągami, a indeks początkowy nie istnieje w ciągu.
Przeciążenia metod, takich jak String.Compare, , String.InsertString.IndexOfString.CompareOrdinalString.LastIndexOfString.LastIndexOfAnyIndexOfAnyRemovelubString.Substring, które umożliwiają określenie indeksu początkowego operacji wymaga, aby indeks był prawidłowym położeniem w ciągu. Prawidłowe indeksy wahają się od 0 do String.Length -1.
Istnieją cztery typowe przyczyny tego ArgumentOutOfRangeException wyjątku:
Pracujesz z pustym ciągiem lub String.Empty. Ponieważ jej String.Length właściwość zwraca wartość 0, każda próba manipulowania nią przez indeks zgłasza ArgumentOutOfRangeException wyjątek. W poniższym przykładzie zdefiniowano metodę
GetFirstCharacter
, która zwraca pierwszy znak ciągu. Jeśli ciąg jest pusty, ponieważ ostatni ciąg przekazany do metody jest, metoda zgłasza ArgumentOutOfRangeException wyjątek.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()
Wyjątek można wyeliminować, testując, czy ciąg String.Length jest większy niż zero, czy przez wywołanie IsNullOrEmpty metody w celu upewnienia się, że ciąg nie
null
jest pusty. Poniższy fragment kodu wykonuje ten ostatni. W takim przypadku, jeśli ciąg jestnull
lub jest pusty,GetFirstCharacter
metoda zwraca wartość 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
Manipulujesz ciągiem na podstawie pozycji podciągu w tym ciągu i nie udało ci się ustalić, czy podciąg został rzeczywiście znaleziony.
Poniższy przykład wyodrębnia drugie słowo frazy dwuskładników. Zgłasza wyjątek ArgumentOutOfRangeException , jeśli fraza składa się tylko z jednego wyrazu i dlatego nie zawiera osadzonego znaku spacji. Dzieje się tak, ponieważ wywołanie String.IndexOf(String) metody zwraca wartość -1, aby wskazać, że wyszukiwanie nie powiodło się, a ta nieprawidłowa wartość jest następnie przekazywana do String.Substring(Int32) metody.
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()
Aby wyeliminować wyjątek, zweryfikuj wartość zwracaną przez metodę wyszukiwania ciągów przed wywołaniem metody manipulowania ciągami.
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
Podjęto próbę wyodrębnienia podciągów spoza zakresu bieżącego ciągu.
Metody wyodrębniające podciągy wymagają określenia pozycji początkowej podciągów i podciągów, które nie będą kontynuowane na końcu ciągu, liczba znaków w podciągu. Należy pamiętać, że nie jest to indeks ostatniego znaku w podciągu.
Wyjątek ArgumentOutOfRangeException jest zwykle zgłaszany w tym przypadku, ponieważ niepoprawnie obliczono liczbę znaków w podciągu. Jeśli używasz metody wyszukiwania, takiej jak String.IndexOf identyfikowanie pozycji początkowych i końcowych podciągów:
Jeśli znak w pozycji końcowej zwróconej przez String.IndexOf ma zostać uwzględniony w podciągu, pozycja końcowa podciągu jest podana przez formułę
endIndex - startIndex + 1
Jeśli znak w pozycji końcowej zwróconej przez String.IndexOf ma zostać wykluczony z podciągu, pozycja końcowa podciągu jest podana przez formułę
endIndex - startIndex
Poniższy przykład definiuje metodę
FindWords
, która używa String.IndexOfAny(Char[], Int32) metody do identyfikowania znaków spacji i znaków interpunkcyjnych w ciągu i zwraca tablicę zawierającą słowa znalezione w ciągu.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'
Przekazano liczbę ujemną do metody z argumentem, który wymaga tylko liczb dodatnich i zera, albo przekazano liczbę ujemną lub zero do metody z argumentem, który wymaga tylko liczb dodatnich.
Na przykład Array.CreateInstance(Type, Int32, Int32, Int32) metoda wymaga określenia liczby elementów w każdym wymiarze tablicy dwuwymiarowej; prawidłowe wartości dla każdego wymiaru mogą wahać się od 0 do Int32.MaxValue. Ale ponieważ argument wymiaru w poniższym przykładzie ma wartość ujemną, metoda zgłasza ArgumentOutOfRangeException wyjątek.
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
Aby naprawić błąd, upewnij się, że wartość nieprawidłowego argumentu jest nie ujemna. Można to zrobić, podając prawidłową wartość, jak wykonuje poniższy fragment kodu.
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)
Możesz również zweryfikować dane wejściowe i, jeśli jest on nieprawidłowy, podjąć jakąś akcję. Poniższy fragment kodu wyświetla komunikat o błędzie zamiast wywoływania metody.
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
Warunek wyścigu istnieje w aplikacji, która jest wielowątkowy lub ma zadania wykonywane asynchronicznie i które aktualizują tablicę lub kolekcję.
W poniższym przykładzie użyto List<T> obiektu do wypełnienia kolekcji
Continent
obiektów. Zwraca ArgumentOutOfRangeException wartość , jeśli przykład próbuje wyświetlić siedem elementów w kolekcji, zanim kolekcja zostanie w pełni wypełniona.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()
W takim przypadku dostęp do dwóch zasobów jest uzyskiwany z wielu wątków:
Kolekcja wystąpień klasy
continents
. Metoda List<T>.Add jest wywoływana z wielu wątków. Ponadto główny lub podstawowy wątek zakłada, że kolekcja jest w pełni wypełniona siedmioma elementami, gdy iteruje jej elementy członkowskie.msg
Ciąg, który jest połączony z wieloma wątkami.
Aby rozwiązać ten błąd, upewnij się, że dostęp do stanu udostępnionego jest dostępny w bezpieczny wątkowo sposób, w następujący sposób.
Jeśli aplikacja używa tablicy lub obiektu kolekcji, rozważ użycie klasy kolekcji bezpiecznej wątkowo, takiej jak typy w System.Collections.Concurrent przestrzeni nazw lub System.Collections.Immutable wydania poza pasmem.
Upewnij się, że dostęp do udostępnionego stanu (czyli zasobów, do których można uzyskać dostęp przez wiele wątków) jest uzyskiwany w bezpieczny wątkowo sposób, dzięki czemu tylko jeden wątek w danym momencie ma wyłączny dostęp do zasobów. Duża liczba klas, takich jak CountdownEvent, , InterlockedMonitori Mutex, jest dostępna do synchronizowania dostępu do zasobów. Aby uzyskać więcej informacji, zobacz Wątkowanie. Ponadto obsługa języka jest dostępna za pośrednictwem instrukcji lock w języku C# i konstrukcji SyncLock w Visual Basic.
Poniższy przykład dotyczy ArgumentOutOfRangeException innych problemów z poprzedniego przykładu. Zastępuje List<T> obiekt obiekt obiektem ConcurrentBag<T> w celu zapewnienia, że dostęp do kolekcji jest bezpieczny wątkowo, używa CountdownEvent obiektu w celu zapewnienia, że wątek aplikacji będzie kontynuowany dopiero po wykonaniu innych wątków i używa blokady w celu zapewnienia, że tylko jeden wątek może uzyskiwać dostęp do
msg
zmiennej w danym momencie.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 używa COR_E_ARGUMENTOUTOFRANGE HRESULT, który ma wartość 0x80131502.
Aby uzyskać listę początkowych wartości właściwości dla wystąpienia programu ArgumentOutOfRangeException, zobacz ArgumentOutOfRangeException konstruktory.
Konstruktory
ArgumentOutOfRangeException() |
Inicjuje nowe wystąpienie klasy ArgumentOutOfRangeException. |
ArgumentOutOfRangeException(SerializationInfo, StreamingContext) |
Przestarzałe.
Inicjuje nowe wystąpienie klasy ArgumentOutOfRangeException z zserializowanymi danymi. |
ArgumentOutOfRangeException(String) |
Inicjuje nowe wystąpienie ArgumentOutOfRangeException klasy o nazwie parametru, który powoduje ten wyjątek. |
ArgumentOutOfRangeException(String, Exception) |
Inicjuje nowe wystąpienie ArgumentOutOfRangeException klasy z określonym komunikatem o błędzie i wyjątkiem, który jest przyczyną tego wyjątku. |
ArgumentOutOfRangeException(String, Object, String) |
Inicjuje nowe wystąpienie ArgumentOutOfRangeException klasy z nazwą parametru, wartością argumentu i określonym komunikatem o błędzie. |
ArgumentOutOfRangeException(String, String) |
Inicjuje nowe wystąpienie ArgumentOutOfRangeException klasy o nazwie parametru, który powoduje ten wyjątek i określony komunikat o błędzie. |
Właściwości
ActualValue |
Pobiera wartość argumentu, która powoduje ten wyjątek. |
Data |
Pobiera kolekcję par klucz/wartość, które zapewniają dodatkowe informacje zdefiniowane przez użytkownika dotyczące wyjątku. (Odziedziczone po Exception) |
HelpLink |
Pobiera lub ustawia link do pliku pomocy skojarzonego z tym wyjątkiem. (Odziedziczone po Exception) |
HResult |
Pobiera lub ustawia HRESULT, zakodowaną wartość liczbową przypisaną do określonego wyjątku. (Odziedziczone po Exception) |
InnerException |
Exception Pobiera wystąpienie, które spowodowało bieżący wyjątek. (Odziedziczone po Exception) |
Message |
Pobiera komunikat o błędzie i ciąg reprezentujący nieprawidłową wartość argumentu lub tylko komunikat o błędzie, jeśli wartość argumentu ma wartość null. |
ParamName |
Pobiera nazwę parametru, który powoduje ten wyjątek. (Odziedziczone po ArgumentException) |
Source |
Pobiera lub ustawia nazwę aplikacji lub obiektu, który powoduje błąd. (Odziedziczone po Exception) |
StackTrace |
Pobiera reprezentację ciągu natychmiastowych ramek w stosie wywołań. (Odziedziczone po Exception) |
TargetSite |
Pobiera metodę, która zgłasza bieżący wyjątek. (Odziedziczone po Exception) |
Metody
Equals(Object) |
Określa, czy dany obiekt jest taki sam, jak bieżący obiekt. (Odziedziczone po Object) |
GetBaseException() |
W przypadku zastąpienia w klasie pochodnej zwraca Exception główną przyczynę co najmniej jednego kolejnego wyjątku. (Odziedziczone po Exception) |
GetHashCode() |
Służy jako domyślna funkcja skrótu. (Odziedziczone po Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Przestarzałe.
SerializationInfo Ustawia obiekt z nieprawidłową wartością argumentu i dodatkowymi informacjami o wyjątku. |
GetObjectData(SerializationInfo, StreamingContext) |
Przestarzałe.
SerializationInfo Ustawia obiekt z nazwą parametru i dodatkowymi informacjami o wyjątku. (Odziedziczone po ArgumentException) |
GetType() |
Pobiera typ środowiska uruchomieniowego bieżącego wystąpienia. (Odziedziczone po Exception) |
MemberwiseClone() |
Tworzy płytkią kopię bieżącego Objectelementu . (Odziedziczone po Object) |
ThrowIfEqual<T>(T, T, String) |
Zgłasza wartość ArgumentOutOfRangeException , jeśli |
ThrowIfGreaterThan<T>(T, T, String) |
Zgłasza wartość ArgumentOutOfRangeException , jeśli |
ThrowIfGreaterThanOrEqual<T>(T, T, String) |
Zgłasza wartość ArgumentOutOfRangeException , jeśli |
ThrowIfLessThan<T>(T, T, String) |
Zgłasza wartość , ArgumentOutOfRangeException jeśli |
ThrowIfLessThanOrEqual<T>(T, T, String) |
Zgłasza wartość , ArgumentOutOfRangeException jeśli |
ThrowIfNegative<T>(T, String) |
Zgłasza wartość ArgumentOutOfRangeException , jeśli |
ThrowIfNegativeOrZero<T>(T, String) |
Zgłasza wartość ArgumentOutOfRangeException , jeśli |
ThrowIfNotEqual<T>(T, T, String) |
Zwraca wartość , ArgumentOutOfRangeException jeśli |
ThrowIfZero<T>(T, String) |
Zgłasza wartość if |
ToString() |
Tworzy i zwraca reprezentację ciągu bieżącego wyjątku. (Odziedziczone po Exception) |
Zdarzenia
SerializeObjectState |
Przestarzałe.
Występuje, gdy wyjątek jest serializowany w celu utworzenia obiektu stanu wyjątku zawierającego serializowane dane o wyjątku. (Odziedziczone po Exception) |