ArgumentOutOfRangeException Třída
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Výjimka, která je vyvolána, když hodnota argumentu je mimo povolený rozsah hodnot definovaný vyvolanou metodou.
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
- Dědičnost
- Dědičnost
- Atributy
- Implementuje
Následující příklad definuje třídu, která bude obsahovat informace o pozvaných hostech. Pokud je host mladší než 21 let, vyvolá se ArgumentOutOfRangeException výjimka.
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
Výjimka ArgumentOutOfRangeException je vyvolána při vyvolání metody a alespoň jeden z argumentů předaných metodě není null
a obsahuje neplatnou hodnotu, která není členem sady hodnot očekávaných pro argument. Vlastnost ParamName identifikuje neplatný argument a ActualValue vlastnost, pokud je k dispozici hodnota, identifikuje neplatnou hodnotu.
Obvykle je ArgumentOutOfRangeException výsledkem chyby vývojáře. Místo zpracování výjimky v try
/catch
bloku byste měli odstranit příčinu výjimky, nebo pokud je argument vrácen voláním metody nebo vstupem uživatele před předáním metodě, která vyvolá výjimku, měli byste před jejich předáním metodě ověřit argumenty.
ArgumentOutOfRangeException je široce používán:
Třídy v System.Collections oborech názvů a System.IO .
Třída Array .
Metody manipulace s řetězci String ve třídě.
Mezi podmínky, ve kterých ArgumentOutOfRangeException je vyvolání výjimky, patří:
Načítáte člena kolekce podle jeho indexového čísla a číslo indexu je neplatné.
Toto je nejčastější příčina ArgumentOutOfRangeException výjimky. Číslo indexu je obvykle neplatné z jednoho ze čtyř důvodů:
Kolekce nemá žádné členy a váš kód předpokládá, že ano. Následující příklad se pokusí načíst první prvek kolekce, která neobsahuje žádné prvky:
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
Chcete-li zabránit výjimce, zkontrolujte
Count
, zda je vlastnost kolekce větší než nula, než se pokusíte načíst všechny členy, jak to dělá následující fragment kódu.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
V některých případech může k výjimce dojít, protože se pokoušíte přidat člena do kolekce pomocí indexu, který neexistuje, místo volání metody, jako
Add
je , která existuje pro tento účel. Následující příklad se pokusí přidat prvek do kolekce pomocí neexistující index místo volání List<T>.Add 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()
Následující fragment kódu tuto chybu opraví:
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
Pokoušíte se načíst položku, jejíž index je záporný. K tomu obvykle dochází, protože jste v kolekci hledali index určitého prvku a mylně jste se domnívali, že hledání bylo úspěšné. V následujícím příkladu se volání List<T>.FindIndex(Predicate<T>) metody nepodaří najít řetězec, který se rovná "Z", a vrátí tak hodnotu -1. Jedná se však o neplatnou hodnotu indexu.
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
Chcete-li zabránit výjimce, před pokusem o načtení položky z kolekce zkontrolujte, zda je vrácené index větší nebo roven nule, zkontrolujte, zda je vyhledávání úspěšné, jak to dělá následující fragment kódu.
// 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
Pokoušíte se načíst prvek, jehož index se rovná hodnotě vlastnosti kolekce
Count
, jak ukazuje následující příklad.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
Vzhledem k tomu, že kolekce v .NET používají indexování založené na nule, je první prvek kolekce na indexu 0 a poslední prvek je v indexu
Count
- 1. Chybu můžete odstranit tak, že zajistíte přístup k poslednímu prvku v indexuCount
– 1, jak to dělá následující kód.// 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
Pokoušíte se provést řetězcovou operaci voláním metody manipulace s řetězci a počáteční index v řetězci neexistuje.
Přetížení metod, jako String.Comparejsou , String.CompareOrdinal, String.IndexOfIndexOfAnyString.LastIndexOfString.Insert, String.LastIndexOfAnyRemovenebo String.Substring které umožňují určit počáteční index operace, vyžadují, aby index byl platnou pozicí v řetězci. Platné indexy jsou v rozsahu od 0 do String.Length – 1.
Existují čtyři běžné příčiny této ArgumentOutOfRangeException výjimky:
Pracujete s prázdným řetězcem nebo String.Empty. Vzhledem k tomu, že jeho String.Length vlastnost vrátí hodnotu 0, vyvolá každý pokus o manipulaci s ním pomocí indexu ArgumentOutOfRangeException výjimku. Následující příklad definuje metodu
GetFirstCharacter
, která vrací první znak řetězce. Pokud je řetězec prázdný, protože poslední řetězec předaný metodě je, metoda vyvolá ArgumentOutOfRangeException výjimku.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()
Výjimku můžete odstranit testováním, zda je řetězec String.Length větší než nula, nebo voláním IsNullOrEmpty metody, aby se zajistilo, že řetězec není
null
nebo prázdný. Následující fragment kódu provede to druhé. V tomto případě, pokud jenull
řetězec nebo prázdný,GetFirstCharacter
vrátí metoda 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
Pracujete s řetězcem na základě pozice podřetězce v daném řetězci a nepodařilo se vám zjistit, jestli byl podřetězc skutečně nalezen.
Následující příklad extrahuje druhé slovo dvouslovné fráze. ArgumentOutOfRangeException Vyvolá výjimku, pokud se fráze skládá pouze z jednoho slova, a proto neobsahuje vložený znak mezery. K tomu dochází, protože volání String.IndexOf(String) metody vrátí hodnotu -1, která označuje, že hledání selhalo, a tato neplatná hodnota je pak předána String.Substring(Int32) metodě.
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()
Chcete-li odstranit výjimku, ověřte hodnotu vrácenou metodou prohledávání řetězců před voláním metody manipulace s řetězci.
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
Pokusili jste se extrahovat podřetězce, který je mimo rozsah aktuálního řetězce.
Metody, které extrahují podřetězce, vyžadují, abyste zadali počáteční pozici podřetězce a u podřetězců, které nepokračují na konec řetězce, počet znaků v podřetězci. Všimněte si, že toto není index posledního znaku v podřetěžci.
V ArgumentOutOfRangeException tomto případě je obvykle vyvolána výjimka, protože jste nesprávně vypočítali počet znaků v podřetězdci. Pokud používáte metodu vyhledávání, například String.IndexOf k identifikaci počáteční a koncové pozice podřetězce:
Pokud má být znak v koncové pozici vrácený uživatelem String.IndexOf zahrnut do podřetězení, je koncová pozice podřetězení daná vzorcem.
endIndex - startIndex + 1
Pokud má být znak v koncové pozici vrácený uživatelem String.IndexOf vyloučen z podřetězení, je koncová pozice podřetězení daná vzorcem.
endIndex - startIndex
Následující příklad definuje metodu
FindWords
, která používá metodu String.IndexOfAny(Char[], Int32) k identifikaci znaků mezery a interpunkčních znamének v řetězci a vrátí pole, které obsahuje slova nalezená v řetězci.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'
Předali jste záporné číslo metodě s argumentem, který vyžaduje pouze kladná čísla a nula, nebo jste předali záporné číslo nebo nulu metodě s argumentem, který vyžaduje pouze kladná čísla.
Metoda například vyžaduje, Array.CreateInstance(Type, Int32, Int32, Int32) abyste zadali počet prvků v každé dimenzi dvojrozměrného pole; platné hodnoty pro každou dimenzi mohou být v rozsahu od 0 do Int32.MaxValue. Ale protože argument dimenze v následujícím příkladu má zápornou hodnotu, metoda vyvolá ArgumentOutOfRangeException výjimku.
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
Pokud chcete chybu opravit, ujistěte se, že hodnota neplatného argumentu není záporná. Můžete to provést zadáním platné hodnoty jako následující fragment kódu.
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)
Vstup můžete také ověřit, a pokud je neplatný, provést nějakou akci. Následující fragment kódu místo volání metody zobrazí chybovou zprávu.
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
Konflikt časování existuje v aplikaci, která je vícevláknová nebo má úlohy, které se spouští asynchronně a které aktualizují pole nebo kolekci.
Následující příklad používá List<T> objekt k naplnění kolekce
Continent
objektů. Vyvolá výjimku , ArgumentOutOfRangeException pokud se příklad pokusí zobrazit sedm položek v kolekci před úplným naplněním kolekce.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()
V tomto případě se ke dvěma prostředkům přistupuje z více vláken:
Kolekce
continents
. Jeho List<T>.Add metoda je volána z více vláken. Kromě toho hlavní nebo primární vlákno předpokládá, že kolekce je plně naplněna sedmi prvky při iteraci svých členů.Řetězec
msg
, který je zřetězen z více vláken.
Pokud chcete chybu opravit, následujícím způsobem se ujistěte, že se ke sdílenému stavu přistupuje způsobem bezpečným pro přístup z více vláken.
Pokud vaše aplikace používá pole nebo objekt kolekce, zvažte použití třídy kolekce bezpečné pro přístup z více vláken, jako jsou typy v System.Collections.Concurrent oboru názvů nebo System.Collections.Immutable vzdálené vydání.
Ujistěte se, že ke sdílenému stavu (tj. k prostředkům, ke kterým může přistupovat více vláken) se přistupuje způsobem bezpečným pro přístup z více vláken, aby k prostředkům mělo výhradní přístup pouze jedno vlákno najednou. Pro synchronizaci přístupu k prostředkům je k dispozici velký počet tříd, jako CountdownEventInterlockedMonitorjsou , , a .Mutex Další informace naleznete v tématu Threading. Kromě toho je podpora jazyků k dispozici prostřednictvím příkazu lock v jazyce C# a konstruktoru SyncLock v jazyce Visual Basic.
Následující příklad řeší ArgumentOutOfRangeException problémy a další problémy z předchozího příkladu. Nahradí List<T> objekt objektem ConcurrentBag<T> , aby se zajistilo, že přístup ke kolekci je bezpečný pro přístup z více vláken, používá CountdownEvent objekt k zajištění, že vlákno aplikace bude pokračovat pouze po spuštění jiných vláken, a pomocí zámku zajistí, že k proměnné může současně přistupovat
msg
pouze jedno vlákno.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 používá COR_E_ARGUMENTOUTOFRANGE HRESULT, který má hodnotu 0x80131502.
Seznam počátečních hodnot vlastností pro instanci najdete v ArgumentOutOfRangeException konstruktorechArgumentOutOfRangeException.
Argument |
Inicializuje novou instanci ArgumentOutOfRangeException třídy. |
Argument |
Zastaralé.
Inicializuje novou instanci třídy ArgumentOutOfRangeException se serializovanými daty. |
Argument |
Inicializuje novou instanci ArgumentOutOfRangeException třídy s názvem parametru, který způsobuje tuto výjimku. |
Argument |
Inicializuje novou instanci ArgumentOutOfRangeException třídy se zadanou chybovou zprávou a výjimkou, která je příčinou této výjimky. |
Argument |
Inicializuje novou instanci ArgumentOutOfRangeException třídy s názvem parametru, hodnotou argumentu a zadanou chybovou zprávou. |
Argument |
Inicializuje novou instanci ArgumentOutOfRangeException třídy s názvem parametru, který způsobuje tuto výjimku, a zadanou chybovou zprávou. |
Actual |
Získá hodnotu argumentu, která způsobuje tuto výjimku. |
Data |
Získá kolekci párů klíč/hodnota, které poskytují další uživatelem definované informace o výjimce. (Zděděno od Exception) |
Help |
Získá nebo nastaví odkaz na soubor nápovědy přidružené k této výjimce. (Zděděno od Exception) |
HResult |
Získá nebo nastaví HRESULT, kódovanou číselnou hodnotu, která je přiřazena ke konkrétní výjimce. (Zděděno od Exception) |
Inner |
Exception Získá instanci, která způsobila aktuální výjimku. (Zděděno od Exception) |
Message |
Získá chybovou zprávu a řetězcovou reprezentaci neplatné hodnoty argumentu nebo pouze chybovou zprávu, pokud je hodnota argumentu null. |
Param |
Získá název parametru, který způsobuje tuto výjimku. (Zděděno od ArgumentException) |
Source |
Získá nebo nastaví název aplikace nebo objektu, který způsobuje chybu. (Zděděno od Exception) |
Stack |
Získá řetězcovou reprezentaci okamžitých rámců v zásobníku volání. (Zděděno od Exception) |
Target |
Získá metodu, která vyvolá aktuální výjimku. (Zděděno od Exception) |
Equals(Object) |
Určí, zda se zadaný objekt rovná aktuálnímu objektu. (Zděděno od Object) |
Get |
Při přepsání v odvozené třídě vrátí Exception hodnotu, která je původní příčinou jedné nebo více následných výjimek. (Zděděno od Exception) |
Get |
Slouží jako výchozí hashovací funkce. (Zděděno od Object) |
Get |
Zastaralé.
Nastaví objekt s SerializationInfo neplatnou hodnotou argumentu a dalšími informacemi o výjimce. |
Get |
Zastaralé.
Nastaví objekt s SerializationInfo názvem parametru a dalšími informacemi o výjimce. (Zděděno od ArgumentException) |
Get |
Získá typ modulu runtime aktuální instance. (Zděděno od Exception) |
Memberwise |
Vytvoří mělkou kopii aktuálního Objectsouboru . (Zděděno od Object) |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException if |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException , pokud |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException , pokud |
Throw |
Vyvolá chybu ArgumentOutOfRangeException , pokud |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException , pokud |
Throw |
Vyvolá příkaz ArgumentOutOfRangeException if |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException , která |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException , která |
Throw |
Vyvolá hodnotu ArgumentOutOfRangeException pokud |
To |
Vytvoří a vrátí řetězcovou reprezentaci aktuální výjimky. (Zděděno od Exception) |
Serialize |
Zastaralé.
Nastane, když je výjimka serializována k vytvoření objektu stavu výjimky, který obsahuje serializovaná data o výjimce. (Zděděno od Exception) |
Produkt | Verze |
---|---|
.NET | Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9 |
.NET Framework | 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Standard | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1 |
UWP | 10.0 |
Zpětná vazba k produktu .NET
.NET je open source projekt. Vyberte odkaz pro poskytnutí zpětné vazby: