ArgumentOutOfRangeException Klass
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Undantaget som utlöses när värdet för ett argument ligger utanför det tillåtna värdeintervallet som definieras av den anropade metoden.
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
- Arv
- Arv
- Attribut
- Implementeringar
Exempel
I följande exempel definieras en klass som innehåller information om en inbjuden gäst. Om gästen är yngre än 21 utlöses ett ArgumentOutOfRangeException undantag.
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
Kommentarer
Ett ArgumentOutOfRangeException undantag utlöses när en metod anropas och minst ett av argumenten som skickas till metoden inte null är och innehåller ett ogiltigt värde som inte är medlem i den uppsättning värden som förväntas för argumentet. Egenskapen ParamName identifierar det ogiltiga argumentet och ActualValue egenskapen identifierar det ogiltiga värdet om ett värde finns.
Vanligtvis ett ArgumentOutOfRangeException resultat från utvecklarfel. I stället för att hantera undantaget i ett try/catch block bör du eliminera orsaken till undantaget, eller om argumentet returneras av ett metodanrop eller indata av användaren innan det skickas till metoden som utlöser undantaget bör du verifiera argumenten innan du skickar dem till metoden.
ArgumentOutOfRangeException används i stor utsträckning av:
Klasser i namnrymderna System.Collections och System.IO .
Klassen Array .
Strängmanipuleringsmetoder i String klassen.
De villkor där ett ArgumentOutOfRangeException undantag utlöses är följande:
Du hämtar medlemmen i en samling med dess indexnummer och indexnumret är ogiltigt.
Det här är den vanligaste orsaken till ett ArgumentOutOfRangeException undantag. Indexnumret är normalt ogiltigt av någon av fyra orsaker:
Samlingen har inga medlemmar och koden förutsätter att den gör det. I följande exempel försöker hämta det första elementet i en samling som inte har några element:
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: indexopen 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: indexOm du vill förhindra undantaget kontrollerar du om samlingens
Countegenskap är större än noll innan du försöker hämta några medlemmar, som följande kodfragment gör.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 IfI vissa fall kan undantaget inträffa eftersom du försöker lägga till en medlem i en samling med hjälp av ett index som inte finns, i stället för att anropa metoden, till exempel , som
Addfinns för det här ändamålet. I följande exempel försöker du lägga till ett element i en samling med hjälp av ett obefintlig index i stället för att anropa List<T>.Add metoden.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()Följande kodfragment korrigerar det här felet:
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)) NextDu försöker hämta ett objekt vars index är negativt. Detta beror vanligtvis på att du har sökt i en samling efter indexet för ett visst element och felaktigt har antagit att sökningen lyckas. I följande exempel kan anropet List<T>.FindIndex(Predicate<T>) till metoden inte hitta en sträng som är lika med "Z" och returnerar därför -1. Detta är dock ett ogiltigt indexvärde.
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: indexopen 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: indexOm du vill förhindra undantaget kontrollerar du att sökningen lyckas genom att se till att det returnerade indexet är större än eller lika med noll innan du försöker hämta objektet från samlingen, som följande kodfragment gör.
// 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 IfDu försöker hämta ett element vars index är lika med värdet för samlingens
Countegenskap, vilket visas i följande exempel.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: indexopen 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: indexEftersom samlingar i .NET använder nollbaserad indexering är det första elementet i samlingen index 0 och det sista elementet är vid indexet
Count- 1. Du kan eliminera felet genom att se till att du får åtkomst till det sista elementet i indexCount- 1, som följande kod gör.// 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
Du försöker utföra en strängåtgärd genom att anropa en strängmanipuleringsmetod och startindexet finns inte i strängen.
Överlagringar av metoder som , , , , , , , , String.Compareeller String.CompareOrdinal som gör att du kan ange startindexet för åtgärden kräver att indexet är en giltig position i strängen. String.IndexOfIndexOfAnyString.InsertString.LastIndexOfString.LastIndexOfAnyRemoveString.Substring Giltiga index varierar från 0 till String.Length - 1.
Det finns fyra vanliga orsaker till det här ArgumentOutOfRangeException undantaget:
Du arbetar med en tom sträng, eller String.Empty. Eftersom dess String.Length egenskap returnerar 0 utlöser alla försök att ändra den med index ett ArgumentOutOfRangeException undantag. I följande exempel definieras en
GetFirstCharactermetod som returnerar det första tecknet i en sträng. Om strängen är tom, som den sista strängen som skickas till metoden, genererar metoden ett ArgumentOutOfRangeException undantag.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()Du kan eliminera undantaget genom att testa om strängens String.Length är större än noll eller genom att anropa IsNullOrEmpty metoden för att säkerställa att strängen inte
nullär eller tom. Följande kodfragment gör det senare. I det här fallet, om strängen ärnulleller tom,GetFirstCharacterreturnerar metoden 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 FunctionDu manipulerar en sträng baserat på positionen för en delsträng i strängen och du har inte kunnat avgöra om delsträngen faktiskt hittades.
I följande exempel extraheras det andra ordet i en fras med två ord. Det utlöser ett ArgumentOutOfRangeException undantag om frasen bara består av ett ord och därför inte innehåller ett inbäddat blankstegstecken. Detta beror på att anropet String.IndexOf(String) till metoden returnerar -1 för att indikera att sökningen misslyckades och det ogiltiga värdet skickas sedan till String.Substring(Int32) metoden.
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()Om du vill eliminera undantaget verifierar du värdet som returneras av strängsökningsmetoden innan du anropar strängmanipuleringsmetoden.
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 citizenopen 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 citizenModule 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 citizenDu har försökt extrahera en delsträng som ligger utanför intervallet för den aktuella strängen.
De metoder som extraherar delsträngar kräver att du anger startpositionen för delsträngen och, för delsträngar som inte fortsätter till slutet av strängen, antalet tecken i understrängen. Observera att detta inte är indexet för det sista tecknet i understrängen.
Ett ArgumentOutOfRangeException undantag utlöses vanligtvis i det här fallet eftersom du felaktigt har beräknat antalet tecken i understrängen. Om du använder en sökmetod som String.IndexOf att identifiera start- och slutpositionerna för en understräng:
Om tecknet i slutpositionen som returneras av String.IndexOf ska inkluderas i delsträngen anges understrängens slutposition av formeln
endIndex - startIndex + 1Om tecknet i slutpositionen som returneras av String.IndexOf ska undantas från delsträngen anges understrängens slutposition av formeln
endIndex - startIndexI följande exempel definieras en
FindWordsmetod som använder String.IndexOfAny(Char[], Int32) metoden för att identifiera blankstegstecken och skiljetecken i en sträng och returnerar en matris som innehåller de ord som finns i strängen.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'
Du har skickat ett negativt tal till en metod med ett argument som endast kräver positiva tal och noll, eller så har du skickat antingen ett negativt tal eller noll till en metod med ett argument som endast kräver positiva tal.
Metoden kräver till exempel Array.CreateInstance(Type, Int32, Int32, Int32) att du anger antalet element i varje dimension i en tvådimensionell matris. Giltiga värden för varje dimension kan variera från 0 till Int32.MaxValue. Men eftersom dimensionsargumentet i följande exempel har ett negativt värde genererar metoden ett ArgumentOutOfRangeException undantag.
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: length2open 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: length2Om du vill korrigera felet kontrollerar du att värdet för det ogiltiga argumentet inte är negativt. Du kan göra detta genom att ange ett giltigt värde, som följande kodfragment gör.
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" arrDim dimension1 As Integer = 10 Dim dimension2 As Integer = 10 Dim arr As Array = Array.CreateInstance(GetType(String), dimension1, dimension2)Du kan också verifiera indata och vidta vissa åtgärder om de är ogiltiga. Följande kodfragment visar ett felmeddelande i stället för att anropa metoden.
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" arrIf 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 IfEtt konkurrensvillkor finns i en app som är flertrådad eller har uppgifter som körs asynkront och som uppdaterar en matris eller samling.
I följande exempel används ett List<T> objekt för att fylla i en samling
Continentobjekt. Det genererar ett ArgumentOutOfRangeException om exemplet försöker visa de sju objekten i samlingen innan samlingen är helt ifylld.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()I det här fallet används två resurser från flera trådar:
Samlingen
continents. Dess List<T>.Add metod anropas från flera trådar. Dessutom förutsätter huvudtråden eller den primära tråden att samlingen är helt ifylld med sju element när den itererar dess medlemmar.Strängen
msg, som sammanfogas från flera trådar.
Åtgärda felet genom att se till att delat tillstånd nås på ett trådsäkert sätt på följande sätt.
Om din app använder en matris eller ett samlingsobjekt bör du överväga att använda en trådsäker samlingsklass, till exempel typerna System.Collections.Concurrent i namnområdet eller out-of-band-versionen System.Collections.Immutable .
Kontrollera att delat tillstånd (det vill säga resurser som kan nås av flera trådar) nås på ett trådsäkert sätt, så att endast en tråd i taget har exklusiv åtkomst till resurserna. Ett stort antal klasser, till exempel CountdownEvent, Interlocked, Monitoroch Mutex, är tillgängliga för att synkronisera åtkomst till resurser. Mer information finns i Trådning. Dessutom är språkstöd tillgängligt via instruktionen lock i C# och SyncLock i Visual Basic.
I följande exempel åtgärdas ArgumentOutOfRangeException och andra problem från föregående exempel. Det ersätter List<T> objektet med ett ConcurrentBag<T> objekt för att säkerställa att åtkomsten till samlingen är trådsäker, använder ett CountdownEvent objekt för att säkerställa att programtråden fortsätter först när andra trådar har körts och använder ett lås för att säkerställa att endast en tråd kan komma åt variabeln
msgi taget.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 0open 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 0Imports 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 använder HRESULT-COR_E_ARGUMENTOUTOFRANGE, som har värdet 0x80131502.
För en lista över inledande egenskapsvärden för en instans av ArgumentOutOfRangeException, se i ArgumentOutOfRangeException-konstruktorn.
Konstruktorer
| Name | Description |
|---|---|
| ArgumentOutOfRangeException() |
Initierar en ny instans av ArgumentOutOfRangeException klassen. |
| ArgumentOutOfRangeException(SerializationInfo, StreamingContext) |
Föråldrad.
Initierar en ny instans av ArgumentOutOfRangeException klassen med serialiserade data. |
| ArgumentOutOfRangeException(String, Exception) |
Initierar en ny instans av ArgumentOutOfRangeException klassen med ett angivet felmeddelande och undantaget som är orsaken till det här undantaget. |
| ArgumentOutOfRangeException(String, Object, String) |
Initierar en ny instans av ArgumentOutOfRangeException klassen med parameternamnet, argumentets värde och ett angivet felmeddelande. |
| ArgumentOutOfRangeException(String, String) |
Initierar en ny instans av ArgumentOutOfRangeException klassen med namnet på parametern som orsakar det här undantaget och ett angivet felmeddelande. |
| ArgumentOutOfRangeException(String) |
Initierar en ny instans av ArgumentOutOfRangeException klassen med namnet på parametern som orsakar det här undantaget. |
Egenskaper
| Name | Description |
|---|---|
| ActualValue |
Hämtar argumentvärdet som orsakar det här undantaget. |
| Data |
Hämtar en samling nyckel/värde-par som ger ytterligare användardefinierad information om undantaget. (Ärvd från Exception) |
| HelpLink |
Hämtar eller anger en länk till hjälpfilen som är associerad med det här undantaget. (Ärvd från Exception) |
| HResult |
Hämtar eller anger HRESULT, ett kodat numeriskt värde som har tilldelats ett specifikt undantag. (Ärvd från Exception) |
| InnerException |
Hämtar den Exception instans som orsakade det aktuella undantaget. (Ärvd från Exception) |
| Message |
Hämtar felmeddelandet och strängrepresentationen av det ogiltiga argumentvärdet, eller bara felmeddelandet om argumentvärdet är null. |
| ParamName |
Hämtar namnet på parametern som orsakar det här undantaget. (Ärvd från ArgumentException) |
| Source |
Hämtar eller anger namnet på programmet eller objektet som orsakar felet. (Ärvd från Exception) |
| StackTrace |
Hämtar en strängrepresentation av de omedelbara ramarna i anropsstacken. (Ärvd från Exception) |
| TargetSite |
Hämtar den metod som utlöser det aktuella undantaget. (Ärvd från Exception) |
Metoder
| Name | Description |
|---|---|
| Equals(Object) |
Avgör om det angivna objektet är lika med det aktuella objektet. (Ärvd från Object) |
| GetBaseException() |
När den åsidosätts i en härledd klass returnerar den Exception som är rotorsaken till ett eller flera efterföljande undantag. (Ärvd från Exception) |
| GetHashCode() |
Fungerar som standard-hash-funktion. (Ärvd från Object) |
| GetObjectData(SerializationInfo, StreamingContext) |
Föråldrad.
Anger objektet SerializationInfo med det ogiltiga argumentvärdet och ytterligare undantagsinformation. |
| GetType() |
Hämtar körningstypen för den aktuella instansen. (Ärvd från Exception) |
| MemberwiseClone() |
Skapar en ytlig kopia av den aktuella Object. (Ärvd från Object) |
| ThrowIfEqual<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfGreaterThan<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfGreaterThanOrEqual<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfLessThan<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfLessThanOrEqual<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfNegative<T>(T, String) |
Kastar ett ArgumentOutOfRangeException om |
| ThrowIfNegativeOrZero<T>(T, String) |
Utlöser ett ArgumentOutOfRangeException om |
| ThrowIfNotEqual<T>(T, T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ThrowIfZero<T>(T, String) |
Genererar ett ArgumentOutOfRangeException om |
| ToString() |
Skapar och returnerar en strängrepresentation av det aktuella undantaget. (Ärvd från Exception) |
Händelser
| Name | Description |
|---|---|
| SerializeObjectState |
Föråldrad.
Inträffar när ett undantag serialiseras för att skapa ett undantagstillståndsobjekt som innehåller serialiserade data om undantaget. (Ärvd från Exception) |