ArgumentOutOfRangeException 클래스
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
인수 값이 호출된 메서드에서 정의한 값의 허용 범위를 벗어날 때 throw되는 예외입니다.
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
- 상속
- 상속
- 특성
- 구현
예제
다음 예제에서는 초대된 게스트에 대한 정보를 포함할 클래스를 정의합니다. 게스트가 21세 미만이면 예외가 ArgumentOutOfRangeException throw됩니다.
using System;
using static System.Console;
public class Program
{
public static void Main(string[] args)
{
try
{
var guest1 = new Guest("Ben", "Miller", 17);
WriteLine(guest1.GuestInfo);
}
catch (ArgumentOutOfRangeException argumentOutOfRangeException)
{
WriteLine($"Error: {argumentOutOfRangeException.Message}");
}
}
}
class Guest
{
private const int minimumRequiredAge = 21;
private string firstName;
private string lastName;
private int age;
public Guest(string firstName, string lastName, int age)
{
if (age < minimumRequiredAge)
throw new ArgumentOutOfRangeException(nameof(age), $"All guests must be {minimumRequiredAge}-years-old or older.");
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public string GuestInfo => $"{firstName} {lastName}, {age}";
}
open System
type Guest(fName: string, lName: string, age: int) =
let minimumRequiredAge = 21
do if age < minimumRequiredAge then
raise (ArgumentOutOfRangeException(nameof age, $"All guests must be {minimumRequiredAge}-years-old or older."))
member _.FirstName = fName
member _.LastName = lName
member _.GuestInfo() = $"{fName} {lName}, {age}"
try
let guest1 = Guest("Ben", "Miller", 17);
printfn $"{guest1.GuestInfo()}"
with
| :? ArgumentOutOfRangeException as e ->
printfn $"Error: {e.Message}"
Module Module1
Public Sub Main()
Try
Dim guest1 As Guest = New Guest("Ben", "Miller", 17)
Console.WriteLine(guest1.GuestInfo)
Catch outOfRange As ArgumentOutOfRangeException
Console.WriteLine("Error: {0}", outOfRange.Message)
End Try
End Sub
End Module
Class Guest
Private FirstName As String
Private LastName As String
Private Age As Integer
Public Sub New(ByVal fName As String, ByVal lName As String, ByVal age As Integer)
MyBase.New()
FirstName = fName
LastName = lName
If (age < 21) Then
Throw New ArgumentOutOfRangeException("age", "All guests must be 21-years-old or older.")
Else
age = age
End If
End Sub
Public Function GuestInfo() As String
Dim gInfo As String = (FirstName + (" " _
+ (Me.LastName + (", " + Me.Age.ToString))))
Return gInfo
End Function
End Class
설명
ArgumentOutOfRangeException 메서드가 호출되고 메서드에 전달된 인수 중 하나 이상이 이 아니 null
고 인수에 필요한 값 집합의 멤버가 아닌 잘못된 값을 포함할 때 예외가 throw됩니다. 속성은 ParamName 잘못된 인수를 식별하고, 값이 ActualValue 있는 경우 속성은 잘못된 값을 식별합니다.
일반적으로 개발자 오류의 ArgumentOutOfRangeException 결과입니다. 블록에서 try
/catch
예외를 처리하는 대신 예외의 원인을 제거하거나 예외를 throw하는 메서드에 전달되기 전에 사용자가 메서드 호출 또는 입력으로 인수를 반환하는 경우 메서드에 전달하기 전에 인수의 유효성을 검사해야 합니다.
ArgumentOutOfRangeException 은 다음과 같은 용도로 광범위하게 사용됩니다.
및 System.IO 네임스페이 System.Collections 스의 클래스입니다.
Array 클래스입니다.
클래스의 문자열 조작 메서드입니다 String .
예외가 ArgumentOutOfRangeException throw되는 조건은 다음과 같습니다.
컬렉션의 멤버를 인덱스 번호로 검색하고 있으며 인덱스 번호가 잘못되었습니다.
이는 예외의 가장 일반적인 원인입니다 ArgumentOutOfRangeException . 일반적으로 인덱스 번호는 다음 네 가지 이유 중 하나로 유효하지 않습니다.
컬렉션에 멤버가 없으며 코드에서 해당 멤버가 있다고 가정합니다. 다음 예제에서는 요소가 없는 컬렉션의 첫 번째 요소를 검색하려고 시도합니다.
using System; using System.Collections.Generic; public class Example4 { public static void Main() { var list = new List<string>(); Console.WriteLine("Number of items: {0}", list.Count); try { Console.WriteLine("The first item: '{0}'", list[0]); } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); } } } // The example displays the following output: // Number of items: 0 // Index was out of range. Must be non-negative and less than the size of the collection. // Parameter name: index
open System let list = ResizeArray<string>() printfn $"Number of items: {list.Count}" try printfn $"The first item: '{list[0]}'" with | :? ArgumentOutOfRangeException as e -> printfn $"{e.Message}" // The example displays the following output: // Number of items: 0 // Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
Imports System.Collections.Generic Module Example Public Sub Main() Dim list As New List(Of String) Console.WriteLine("Number of items: {0}", list.Count) Try Console.WriteLine("The first item: '{0}'", list(0)) Catch e As ArgumentOutOfRangeException Console.WriteLine(e.Message) End Try End Sub End Module ' The example displays the following output: ' Number of items: 0 ' Index was out of range. Must be non-negative and less than the size of the collection. ' Parameter name: index
예외를 방지하려면 다음 코드 조각과 같이 멤버를 검색하기 전에 컬렉션의
Count
속성이 0보다 큰지 여부를 검사.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
경우에 따라 이 목적을 위해 존재하는 와 같은
Add
메서드를 호출하는 대신 존재하지 않는 인덱스를 사용하여 컬렉션에 멤버를 추가하려고 하기 때문에 예외가 발생할 수 있습니다. 다음 예제에서는 메서드를 호출 List<T>.Add 하는 대신 존재하지 않는 인덱스를 사용하여 컬렉션에 요소를 추가하려고 합니다.using System; using System.Collections.Generic; public class Example13 { public static void Main() { var numbers = new List<int>(); numbers.AddRange( new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 } ); var squares = new List<int>(); for (int ctr = 0; ctr < numbers.Count; ctr++) squares[ctr] = (int) Math.Pow(numbers[ctr], 2); } } // The example displays the following output: // Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. // Parameter name: index // at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) // at Example.Main()
let numbers = ResizeArray<int>() numbers.AddRange [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 20 ] let squares = ResizeArray<int>() for ctr = 0 to numbers.Count - 1 do squares[ctr] <- int (float numbers[ctr] ** 2) // The example displays the following output: // Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') // at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) // at <StartupCode$argumentoutofrangeexception>.$NoElements.main@()
Imports System.Collections.Generic Module Example Public Sub Main() Dim numbers As New List(Of Integer) numbers.AddRange( { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 } ) Dim squares As New List(Of Integer) For ctr As Integer = 0 To numbers.Count - 1 squares(ctr) = CInt(numbers(ctr) ^ 2) Next End Sub End Module ' The example displays the following output: ' Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. ' Parameter name: index ' at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) ' at Example.Main()
다음 코드 조각은 이 오류를 수정합니다.
var squares = new List<int>(); for (int ctr = 0; ctr < numbers.Count; ctr++) squares.Add((int) Math.Pow(numbers[ctr], 2));
let squares = ResizeArray<int>() for ctr = 0 to numbers.Count - 1 do squares.Add(int (float numbers[ctr] ** 2))
Dim squares As New List(Of Integer) For ctr As Integer = 0 To numbers.Count - 1 squares.Add(CInt(numbers(ctr) ^ 2)) Next
인덱스가 음수인 항목을 검색하려고 합니다. 이는 일반적으로 특정 요소의 인덱스에 대한 컬렉션을 검색했고 검색이 성공했다고 잘못 가정했기 때문에 발생합니다. 다음 예제에서는 메서드 호출이 List<T>.FindIndex(Predicate<T>) "Z"와 같은 문자열을 찾지 못하므로 -1을 반환합니다. 그러나 잘못된 인덱스 값입니다.
using System; using System.Collections.Generic; public class Example { public static void Main() { var list = new List<string>(); list.AddRange( new String[] { "A", "B", "C" } ); // Get the index of the element whose value is "Z". int index = list.FindIndex((new StringSearcher("Z")).FindEquals); try { Console.WriteLine("Index {0} contains '{1}'", index, list[index]); } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); } } } internal class StringSearcher { string value; public StringSearcher(string value) { this.value = value; } public bool FindEquals(string s) { return s.Equals(value, StringComparison.InvariantCulture); } } // The example displays the following output: // Index was out of range. Must be non-negative and less than the size of the collection. // Parameter name: index
open System module StringSearcher = let findEquals (s: string) value = s.Equals(value, StringComparison.InvariantCulture) let list = ResizeArray<string>() list.AddRange [ "A"; "B"; "C" ] // Get the index of the element whose value is "Z". let index = list.FindIndex(StringSearcher.findEquals "Z") try printfn $"Index {index} contains '{list[index]}'" with | :? ArgumentOutOfRangeException as e -> printfn $"{e.Message}" // The example displays the following output: // Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
Imports System.Collections.Generic Module Example Public Sub Main() Dim list As New List(Of String) list.AddRange( { "A", "B", "C" } ) ' Get the index of the element whose value is "Z". Dim index As Integer = list.FindIndex(AddressOf (New StringSearcher("Z")).FindEquals) Try Console.WriteLine("Index {0} contains '{1}'", index, list(index)) Catch e As ArgumentOutOfRangeException Console.WriteLine(e.Message) End Try End Sub End Module Friend Class StringSearcher Dim value As String Public Sub New(value As String) Me.value = value End Sub Public Function FindEquals(s As String) As Boolean Return s.Equals(value, StringComparison.InvariantCulture) End Function End Class ' The example displays the following output: ' Index was out of range. Must be non-negative and less than the size of the collection. ' Parameter name: index
예외를 방지하려면 다음 코드 조각과 같이 컬렉션에서 항목을 검색하기 전에 반환된 인덱스가 0보다 크거나 같은지 확인하여 검색이 성공하는지 검사.
// 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
다음 예제와 같이 인덱스가 컬렉션
Count
의 속성 값과 같은 요소를 검색하려고 합니다.using System; using System.Collections.Generic; public class Example8 { public static void Main() { var list = new List<string>(); list.AddRange( new String[] { "A", "B", "C" } ); try { // Display the elements in the list by index. for (int ctr = 0; ctr <= list.Count; ctr++) Console.WriteLine("Index {0}: {1}", ctr, list[ctr]); } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); } } } // The example displays the following output: // Index 0: A // Index 1: B // Index 2: C // Index was out of range. Must be non-negative and less than the size of the collection. // Parameter name: index
open System let list = ResizeArray<string>() list.AddRange [ "A"; "B"; "C" ] try // Display the elements in the list by index. for i = 0 to list.Count do printfn $"Index {i}: {list[i]}" with | :? ArgumentOutOfRangeException as e -> printfn $"{e.Message}" // The example displays the following output: // Index 0: A // Index 1: B // Index 2: C // Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
Imports System.Collections.Generic Module Example Public Sub Main() Dim list As New List(Of String) list.AddRange( { "A", "B", "C" } ) Try ' Display the elements in the list by index. For ctr As Integer = 0 To list.Count Console.WriteLine("Index {0}: {1}", ctr, list(ctr)) Next Catch e As ArgumentOutOfRangeException Console.WriteLine(e.Message) End Try End Sub End Module ' The example displays the following output: ' Index 0: A ' Index 1: B ' Index 2: C ' Index was out of range. Must be non-negative and less than the size of the collection. ' Parameter name: index
.NET의 컬렉션은 0부터 시작하는 인덱싱을 사용하므로 컬렉션의 첫 번째 요소는 인덱스 0에 있고 마지막 요소는 인덱
Count
스 - 1에 있습니다. 다음 코드와 같이 인덱Count
스 - 1의 마지막 요소에 액세스하도록 하여 오류를 제거할 수 있습니다.// Display the elements in the list by index. for (int ctr = 0; ctr < list.Count; ctr++) Console.WriteLine("Index {0}: {1}", ctr, list[ctr]);
// Display the elements in the list by index. for i = 0 to list.Count - 1 do printfn $"Index {i}: {list[i]}"
' Display the elements in the list by index. For ctr As Integer = 0 To list.Count - 1 Console.WriteLine("Index {0}: {1}", ctr, list(ctr)) Next
문자열 조작 메서드를 호출하여 문자열 작업을 수행하려고 하며 문자열에 시작 인덱스가 없습니다.
작업의 시작 인덱스를 지정할 수 있는 , , String.CompareOrdinal, String.IndexOfIndexOfAny, String.LastIndexOfAnyString.LastIndexOfString.InsertRemove, 또는 String.Substring 와 같은 String.Compare메서드의 오버로드는 인덱스가 문자열 내에서 유효한 위치여야 합니다. 유효한 인덱스 범위는 0에서 1까지 String.Length 입니다.
이 ArgumentOutOfRangeException 예외의 일반적인 원인은 다음과 같습니다.
빈 문자열 또는 String.Empty로 작업하고 있습니다. 속성이 0을 String.Length 반환하므로 인덱스로 조작하려고 하면 예외가 ArgumentOutOfRangeException throw됩니다. 다음 예제에서는 문자열의 첫 번째 문자를 반환하는 메서드를 정의
GetFirstCharacter
합니다. 문자열이 비어 있으면 메서드에 전달된 마지막 문자열이 이면 메서드가 예외를 ArgumentOutOfRangeException throw합니다.using System; public class Example1 { public static void Main() { String[] words = { "the", "today", "tomorrow", " ", "" }; foreach (var word in words) Console.WriteLine("First character of '{0}': '{1}'", word, GetFirstCharacter(word)); } private static char GetFirstCharacter(string s) { return s[0]; } } // The example displays the following output: // First character of //the//: //t// // First character of //today//: //t// // First character of //tomorrow//: //t// // First character of // //: // // // // Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. // at Example.Main()
open System let getFirstCharacter (s: string) = s[0] let words = [ "the"; "today"; "tomorrow"; " "; "" ] for word in words do printfn $"First character of '{word}': '{getFirstCharacter word}'" // The example displays the following output: // First character of 'the': 't' // First character of 'today': 't' // First character of 'tomorrow': 't' // First character of ' ': ' ' // // Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. // at <StartupCode$argumentoutofrangeexception>.$EmptyString1.main@()
Module Example Public Sub Main() Dim words() As String = { "the", "today", "tomorrow", " ", "" } For Each word In words Console.WriteLine("First character of '{0}': '{1}'", word, GetFirstCharacter(word)) Next End Sub Private Function GetFirstCharacter(s As String) As Char Return s(0) End Function End Module ' The example displays the following output: ' First character of 'the': 't' ' First character of 'today': 't' ' First character of 'tomorrow': 't' ' First character of ' ': ' ' ' ' Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. ' at Example.Main()
문자열의 String.Length 가 0보다 큰지 테스트하거나 메서드를 호출 IsNullOrEmpty 하여 문자열이 비어 있지 않은지
null
확인하여 예외를 제거할 수 있습니다. 다음 코드 조각은 후자를 수행합니다. 이 경우 문자열이null
비어 있거나 비어 있으면 메서드는GetFirstCharacter
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
해당 문자열 내의 부분 문자열 위치에 따라 문자열을 조작하고 있으며 부분 문자열이 실제로 발견되었는지 여부를 결정하지 못했습니다.
다음 예제에서는 두 단어 구의 두 번째 단어를 추출합니다. 구문이 ArgumentOutOfRangeException 하나의 단어로만 구성되므로 포함된 공백 문자가 포함되지 않은 경우 예외가 throw됩니다. 이는 메서드에 대한 호출이 검색에 실패했음을 String.IndexOf(String) 나타내기 위해 -1을 반환하고 이 잘못된 값이 메서드에 String.Substring(Int32) 전달되기 때문에 발생합니다.
using System; public class Example17 { public static void Main() { String[] phrases = { "ocean blue", "concerned citizen", "runOnPhrase" }; foreach (var phrase in phrases) Console.WriteLine("Second word is {0}", GetSecondWord(phrase)); } static string GetSecondWord(string s) { int pos = s.IndexOf(" "); return s.Substring(pos).Trim(); } } // The example displays the following output: // Second word is blue // Second word is citizen // // Unhandled Exception: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. // Parameter name: startIndex // at System.String.Substring(Int32 startIndex, Int32 length) // at Example17.GetSecondWord(String s) // at Example17.Main()
let getSecondWord (s: string) = let pos = s.IndexOf " " s.Substring(pos).Trim() let phrases = [ "ocean blue"; "concerned citizen"; "runOnPhrase" ] for phrase in phrases do printfn $"Second word is {getSecondWord phrase}" // The example displays the following output: // Second word is blue // Second word is citizen // // Unhandled Exception: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. (Parameter 'startIndex') // at System.String.Substring(Int32 startIndex, Int32 length) // at System.String.Substring(Int32 startIndex) // at NoFind1.getSecondWord(String s) // at <StartupCode$argumentoutofrangeexception>.$NoFind1.main@()
Module Example Public Sub Main() Dim phrases() As String = { "ocean blue", "concerned citizen", "runOnPhrase" } For Each phrase In phrases Console.WriteLine("Second word is {0}", GetSecondWord(phrase)) Next End Sub Function GetSecondWord(s As String) As String Dim pos As Integer = s.IndexOf(" ") Return s.Substring(pos).Trim() End Function End Module ' The example displays the following output: ' Second word is blue ' Second word is citizen ' ' Unhandled Exception: System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. ' Parameter name: startIndex ' at System.String.Substring(Int32 startIndex, Int32 length) ' at Example.GetSecondWord(String s) ' at Example.Main()
예외를 제거하려면 문자열 조작 메서드를 호출하기 전에 문자열 검색 메서드에서 반환된 값의 유효성을 검사합니다.
using System; public class Example18 { public static void Main() { String[] phrases = { "ocean blue", "concerned citizen", "runOnPhrase" }; foreach (var phrase in phrases) { string word = GetSecondWord(phrase); if (! string.IsNullOrEmpty(word)) Console.WriteLine("Second word is {0}", word); } } static string GetSecondWord(string s) { int pos = s.IndexOf(" "); if (pos >= 0) return s.Substring(pos).Trim(); else return string.Empty; } } // The example displays the following output: // Second word is blue // Second word is citizen
open System let getSecondWord (s: string) = let pos = s.IndexOf " " if pos >= 0 then s.Substring(pos).Trim() else String.Empty let phrases = [ "ocean blue"; "concerned citizen"; "runOnPhrase" ] for phrase in phrases do let word = getSecondWord phrase if not (String.IsNullOrEmpty word) then printfn $"Second word is {word}" // The example displays the following output: // Second word is blue // Second word is citizen
Module Example Public Sub Main() Dim phrases() As String = { "ocean blue", "concerned citizen", "runOnPhrase" } For Each phrase In phrases Dim word As String = GetSecondWord(phrase) If Not String.IsNullOrEmpty(word) Then _ Console.WriteLine("Second word is {0}", word) Next End Sub Function GetSecondWord(s As String) As String Dim pos As Integer = s.IndexOf(" ") If pos >= 0 Return s.Substring(pos).Trim() Else Return String.Empty End If End Function End Module ' The example displays the following output: ' Second word is blue ' Second word is citizen
현재 문자열 범위를 벗어나는 부분 문자열을 추출하려고 했습니다.
부분 문자열을 추출하는 메서드는 모두 부분 문자열의 시작 위치를 지정해야 하며 문자열의 끝까지 계속되지 않는 부분 문자열의 경우 부분 문자열의 문자 수를 지정해야 합니다. 부분 문자열의 마지막 문자 인덱 스가 아닙니다.
ArgumentOutOfRangeException 부분 문자열의 문자 수를 잘못 계산했기 때문에 이 경우 일반적으로 예외가 throw됩니다. 와 같은 String.IndexOf 검색 방법을 사용하여 부분 문자열의 시작 및 끝 위치를 식별하는 경우:
에서 반환 String.IndexOf 된 끝 위치의 문자가 부분 문자열에 포함되는 경우 수식에서 부분 문자열의 끝 위치를 지정합니다.
endIndex - startIndex + 1
에서 반환 String.IndexOf 된 끝 위치의 문자가 부분 문자열에서 제외되는 경우 부분 문자열의 끝 위치는 수식에 의해 지정됩니다.
endIndex - startIndex
다음 예제에서는 메서드를
FindWords
사용하여 String.IndexOfAny(Char[], Int32) 문자열의 공백 문자와 문장 부호를 식별하고 문자열에 있는 단어가 포함된 배열을 반환하는 메서드를 정의합니다.using System; using System.Collections.Generic; public class Example19 { public static void Main() { string sentence = "This is a simple, short sentence."; Console.WriteLine("Words in '{0}':", sentence); foreach (var word in FindWords(sentence)) Console.WriteLine(" '{0}'", word); } static String[] FindWords(string s) { int start = 0, end = 0; Char[] delimiters = { ' ', '.', ',', ';', ':', '(', ')' }; var words = new List<string>(); while (end >= 0) { end = s.IndexOfAny(delimiters, start); if (end >= 0) { if (end - start > 0) words.Add(s.Substring(start, end - start)); start = end + 1; } else { if (start < s.Length - 1) words.Add(s.Substring(start)); } } return words.ToArray(); } } // The example displays the following output: // Words in 'This is a simple, short sentence.': // 'This' // 'is' // 'a' // 'simple' // 'short' // 'sentence'
let findWords (s: string) = let mutable start, end' = 0, 0 let delimiters = [| ' '; '.'; ','; ';'; ':'; '('; ')' |] let words = ResizeArray<string>() while end' >= 0 do end' <- s.IndexOfAny(delimiters, start) if end' >= 0 then if end' - start > 0 then words.Add(s.Substring(start, end' - start)) start <- end' + 1 elif start < s.Length - 1 then words.Add(s.Substring start) words.ToArray() let sentence = "This is a simple, short sentence." printfn $"Words in '{sentence}':" for word in findWords sentence do printfn $" '{word}'" // The example displays the following output: // Words in 'This is a simple, short sentence.': // 'This' // 'is' // 'a' // 'simple' // 'short' // 'sentence'
Imports System.Collections.Generic Module Example Public Sub Main() Dim sentence As String = "This is a simple, short sentence." Console.WriteLine("Words in '{0}':", sentence) For Each word In FindWords(sentence) Console.WriteLine(" '{0}'", word) Next End Sub Function FindWords(s As String) As String() Dim start, ending As Integer Dim delimiters() As Char = { " "c, "."c, ","c, ";"c, ":"c, "("c, ")"c } Dim words As New List(Of String)() Do While ending >= 0 ending = s.IndexOfAny(delimiters, start) If ending >= 0 If ending - start > 0 Then words.Add(s.Substring(start, ending - start)) End If start = ending + 1 Else If start < s.Length - 1 Then words.Add(s.Substring(start)) End If End If Loop Return words.ToArray() End Function End Module ' The example displays the following output: ' Words in 'This is a simple, short sentence.': ' 'This' ' 'is' ' 'a' ' 'simple' ' 'short' ' 'sentence'
양수와 0만 필요한 인수가 있는 메서드에 음수를 전달했거나 양수만 필요한 인수가 있는 메서드에 음수 또는 0을 전달했습니다.
예를 들어 메서드를 Array.CreateInstance(Type, Int32, Int32, Int32) 사용하려면 2차원 배열의 각 차원에 있는 요소 수를 지정해야 합니다. 각 차원의 유효한 값은 0에서 입니다 Int32.MaxValue. 그러나 다음 예제의 차원 인수에 음수 값이 있으므로 메서드는 예외를 ArgumentOutOfRangeException throw합니다.
using System; public class Example01 { public static void Main() { int dimension1 = 10; int dimension2 = -1; try { Array arr = Array.CreateInstance(typeof(string), dimension1, dimension2); } catch (ArgumentOutOfRangeException e) { if (e.ActualValue != null) Console.WriteLine("{0} is an invalid value for {1}: ", e.ActualValue, e.ParamName); Console.WriteLine(e.Message); } } } // The example displays the following output: // Non-negative number required. // Parameter name: length2
open System let dimension1 = 10 let dimension2 = -1 try let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2) printfn "%A" arr with | :? ArgumentOutOfRangeException as e -> if not (isNull e.ActualValue) then printfn $"{e.ActualValue} is an invalid value for {e.ParamName}: " printfn $"{e.Message}" // The example displays the following output: // Non-negative number required. (Parameter 'length2')
Module Example Public Sub Main() Dim dimension1 As Integer = 10 Dim dimension2 As Integer = -1 Try Dim arr AS Array = Array.CreateInstance(GetType(String), dimension1, dimension2) Catch e As ArgumentOutOfRangeException If e.ActualValue IsNot Nothing Then Console.WriteLine("{0} is an invalid value for {1}: ", e.ActualValue, e.ParamName) End If Console.WriteLine(e.Message) End Try End Sub End Module ' The example displays the following output: ' Non-negative number required. ' Parameter name: length2
오류를 수정하려면 잘못된 인수의 값이 음수가 아닌지 확인합니다. 다음 코드 조각처럼 유효한 값을 제공하여 이 작업을 수행할 수 있습니다.
int dimension1 = 10; int dimension2 = 10; Array arr = Array.CreateInstance(typeof(string), dimension1, dimension2);
let dimension1 = 10 let dimension2 = 10 let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2) printfn "%A" arr
Dim dimension1 As Integer = 10 Dim dimension2 As Integer = 10 Dim arr As Array = Array.CreateInstance(GetType(String), dimension1, dimension2)
입력의 유효성을 검사하고 잘못된 경우 몇 가지 작업을 수행할 수도 있습니다. 다음 코드 조각은 메서드를 호출하는 대신 오류 메시지를 표시합니다.
if (dimension1 < 0 || dimension2 < 0) { Console.WriteLine("Unable to create the array."); Console.WriteLine("Specify non-negative values for the two dimensions."); } else { arr = Array.CreateInstance(typeof(string), dimension1, dimension2); }
if dimension1 < 0 || dimension2 < 0 then printfn "Unable to create the array." printfn "Specify non-negative values for the two dimensions." else let arr = Array.CreateInstance(typeof<string>, dimension1, dimension2) printfn "%A" arr
If dimension1 < 0 OrElse dimension2 < 0 Then Console.WriteLine("Unable to create the array.") Console.WriteLine("Specify non-negative values for the two dimensions.") Else arr = Array.CreateInstance(GetType(String), dimension1, dimension2) End If
다중 스레드되거나 비동기적으로 실행되고 배열 또는 컬렉션을 업데이트하는 태스크가 있는 앱에 경합 조건이 있습니다.
다음 예제에서는 개체를 List<T> 사용하여 개체 컬렉션을
Continent
채웁습니다. 컬렉션이 ArgumentOutOfRangeException 완전히 채워지기 전에 예제에서 컬렉션의 7개 항목을 표시하려고 하면 을 throw합니다.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()
이 경우 여러 스레드에서 두 개의 리소스에 액세스합니다.
continents
컬렉션입니다. 해당 List<T>.Add 메서드는 여러 스레드에서 호출됩니다. 또한 기본 또는 기본 스레드는 컬렉션이 멤버를 반복할 때 7개의 요소로 완전히 채워져 있다고 가정합니다.msg
여러 스레드에서 연결된 문자열입니다.
오류를 수정하려면 다음과 같이 스레드로부터 안전한 방식으로 공유 상태에 액세스해야 합니다.
앱에서 배열 또는 컬렉션 개체를 사용하는 경우 네임스페이스의 형식 System.Collections.Concurrent 또는 대역 외 릴리스와 같은 스레드로부터 안전한 컬렉션 클래스를 System.Collections.Immutable 사용하는 것이 좋습니다.
한 번에 하나의 스레드만 리소스에 단독으로 액세스할 수 있도록 공유 상태(즉, 여러 스레드에서 액세스할 수 있는 리소스)가 스레드로부터 안전한 방식으로 액세스되는지 확인합니다. , , InterlockedMonitor및 와 Mutex같은 CountdownEvent많은 클래스를 사용하여 리소스에 대한 액세스를 동기화할 수 있습니다. 자세한 내용은 스레딩을 참조하세요. 또한 언어 지원은 C#의 lock 문과 Visual Basic의 SyncLock 구문을 통해 사용할 수 있습니다.
다음 예제에서는 및 이전 예제의 다른 문제를 해결 ArgumentOutOfRangeException 합니다. 개체를 List<T> 개체로 ConcurrentBag<T> 바꿔 컬렉션에 대한 액세스가 스레드로부터 안전한지 확인하고, 개체를 CountdownEvent 사용하여 다른 스레드가 실행된 후에만 애플리케이션 스레드가 계속되도록 하고, 잠금을 사용하여 한 번에 하나의 스레드만 변수에
msg
액세스할 수 있도록 합니다.using System; using System.Collections.Concurrent; using System.Threading; public class ContinentD { public string? Name { get; set; } public int Population { get; set; } public Decimal Area { get; set; } } public class Example12 { static ConcurrentBag<ContinentD> ContinentDs = new ConcurrentBag<ContinentD>(); static CountdownEvent? gate; static string msg = string.Empty; public static void Main() { String[] names = { "Africa", "Antarctica", "Asia", "Australia", "Europe", "North America", "South America" }; gate = new CountdownEvent(names.Length); // Populate the list. foreach (var name in names) { var th = new Thread(PopulateContinentDs); th.Start(name); } // Display the list. gate.Wait(); Console.WriteLine(msg); Console.WriteLine(); var arr = ContinentDs.ToArray(); for (int ctr = 0; ctr < names.Length; ctr++) { var ContinentD = arr[ctr]; Console.WriteLine("{0}: Area: {1}, Population {2}", ContinentD.Name, ContinentD.Population, ContinentD.Area); } } private static void PopulateContinentDs(Object? obj) { string? name = obj?.ToString(); lock(msg) { msg += string.Format("Adding '{0}' to the list.\n", name); } var ContinentD = new ContinentD(); ContinentD.Name = name; // Sleep to simulate retrieving remaining data. Thread.Sleep(25); ContinentDs.Add(ContinentD); gate?.Signal(); } } // The example displays output like the following: // Adding 'Africa' to the list. // Adding 'Antarctica' to the list. // Adding 'Asia' to the list. // Adding 'Australia' to the list. // Adding 'Europe' to the list. // Adding 'North America' to the list. // Adding 'South America' to the list. // // // Africa: Area: 0, Population 0 // Antarctica: Area: 0, Population 0 // Asia: Area: 0, Population 0 // Australia: Area: 0, Population 0 // Europe: Area: 0, Population 0 // North America: Area: 0, Population 0 // South America: Area: 0, Population 0
open System.Collections.Concurrent open System.Threading type Continent = { Name: string Population: int Area: decimal } let continents = ConcurrentBag<Continent>(); let mutable msg = "" let names = [ "Africa"; "Antarctica"; "Asia" "Australia"; "Europe"; "North America" "South America" ] let gate = new CountdownEvent(names.Length) let populateContinents obj = let name = string obj lock msg (fun () -> msg <- msg + $"Adding '{name}' to the list.\n" ) // Sleep to simulate retrieving remaining data. let continent = { Name = name Population = 0 Area = 0M } Thread.Sleep 25 continents.Add continent gate.Signal() |> ignore // Populate the list. for name in names do let th = Thread(ParameterizedThreadStart populateContinents) th.Start name // Display the list. gate.Wait(); printfn $"{msg}\n" let arr = continents.ToArray(); for i = 0 to names.Length - 1 do let continent = arr[i] printfn $"{continent.Name}: Area: {continent.Population}, Population {continent.Area}" // The example displays output like the following: // Adding 'Africa' to the list. // Adding 'Antarctica' to the list. // Adding 'Asia' to the list. // Adding 'Australia' to the list. // Adding 'Europe' to the list. // Adding 'North America' to the list. // Adding 'South America' to the list. // // // Africa: Area: 0, Population 0 // Antarctica: Area: 0, Population 0 // Asia: Area: 0, Population 0 // Australia: Area: 0, Population 0 // Europe: Area: 0, Population 0 // North America: Area: 0, Population 0 // South America: Area: 0, Population 0
Imports System.Collections.Concurrent Imports System.Threading Public Class Continent Public Property Name As String Public Property Population As Integer Public Property Area As Decimal End Class Module Example Dim continents As New ConcurrentBag(Of Continent) Dim gate As CountdownEvent Dim msg As String = String.Empty Public Sub Main() Dim names() As String = { "Africa", "Antarctica", "Asia", "Australia", "Europe", "North America", "South America" } gate = new CountdownEvent(names.Length) ' Populate the list. For Each name In names Dim th As New Thread(AddressOf PopulateContinents) th.Start(name) Next ' Display the list. gate.Wait() Console.WriteLine(msg) Console.WriteLine() For ctr As Integer = 0 To names.Length - 1 Dim continent = continents(ctr) Console.WriteLine("{0}: Area: {1}, Population {2}", continent.Name, continent.Population, continent.Area) Next End Sub Private Sub PopulateContinents(obj As Object) Dim name As String = obj.ToString() SyncLock msg msg += String.Format("Adding '{0}' to the list.{1}", name, vbCrLf) End SyncLock Dim continent As New Continent() continent.Name = name ' Sleep to simulate retrieving remaining data. Thread.Sleep(25) continents.Add(continent) gate.Signal() End Sub End Module ' The example displays output like the following: ' Adding 'Africa' to the list. ' Adding 'Antarctica' to the list. ' Adding 'Asia' to the list. ' Adding 'Australia' to the list. ' Adding 'Europe' to the list. ' Adding 'North America' to the list. ' Adding 'South America' to the list. ' ' ' Africa: Area: 0, Population 0 ' Antarctica: Area: 0, Population 0 ' Asia: Area: 0, Population 0 ' Australia: Area: 0, Population 0 ' Europe: Area: 0, Population 0 ' North America: Area: 0, Population 0 ' South America: Area: 0, Population 0
ArgumentOutOfRangeException 는 값이 0x80131502 HRESULT COR_E_ARGUMENTOUTOFRANGE 사용합니다.
인스턴스의 초기 속성 값의 목록을 ArgumentOutOfRangeException, 참조는 ArgumentOutOfRangeException 생성자입니다.
생성자
ArgumentOutOfRangeException() |
ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
ArgumentOutOfRangeException(SerializationInfo, StreamingContext) |
사용되지 않음.
serialize된 데이터를 사용하여 ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
ArgumentOutOfRangeException(String) |
이 예외를 throw한 매개 변수의 이름을 사용하여 ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
ArgumentOutOfRangeException(String, Exception) |
지정된 오류 메시지와 이 예외를 발생시킨 예외를 사용하여 ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
ArgumentOutOfRangeException(String, Object, String) |
매개 변수 이름, 인수 값 및 지정된 오류 메시지를 사용하여 ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
ArgumentOutOfRangeException(String, String) |
이 예외를 발생시킨 매개 변수의 이름과 지정된 오류 메시지를 사용하여 ArgumentOutOfRangeException 클래스의 새 인스턴스를 초기화합니다. |
속성
ActualValue |
이 예외를 발생시킨 인수 값을 가져옵니다. |
Data |
예외에 대한 사용자 정의 정보를 추가로 제공하는 키/값 쌍 컬렉션을 가져옵니다. (다음에서 상속됨 Exception) |
HelpLink |
이 예외와 연결된 도움말 파일에 대한 링크를 가져오거나 설정합니다. (다음에서 상속됨 Exception) |
HResult |
특정 예외에 할당된 코드화된 숫자 값인 HRESULT를 가져오거나 설정합니다. (다음에서 상속됨 Exception) |
InnerException |
현재 예외를 발생시킨 Exception 인스턴스를 가져옵니다. (다음에서 상속됨 Exception) |
Message |
오류 메시지 및 잘못된 인수 값의 문자열 표현을 가져오거나, 인수 값이 Null인 경우 오류 메시지만 가져옵니다. |
ParamName |
이 예외를 발생시킨 매개 변수의 이름을 가져옵니다. (다음에서 상속됨 ArgumentException) |
Source |
오류를 발생시키는 애플리케이션 또는 개체의 이름을 가져오거나 설정합니다. (다음에서 상속됨 Exception) |
StackTrace |
호출 스택의 직접 실행 프레임 문자열 표현을 가져옵니다. (다음에서 상속됨 Exception) |
TargetSite |
현재 예외를 throw하는 메서드를 가져옵니다. (다음에서 상속됨 Exception) |
메서드
이벤트
SerializeObjectState |
사용되지 않음.
예외에 대한 serialize된 데이터가 들어 있는 예외 상태 개체가 만들어지도록 예외가 serialize될 때 발생합니다. (다음에서 상속됨 Exception) |
적용 대상
추가 정보
.NET