2009-08-31 6 views
50

주어진 문자열 매개 변수를 사용하는 메소드를 작업하고 있습니다. string 매개 변수의 유효한 값은 null 또는 string.Empty 이외의 값입니다. 그래서 내 코드는 이렇게 보입니다.문자열이 비어 있으면 ArgumentNullException을 발생시켜야합니까?

너무 흥미로운 것은 없습니다. 제 질문은 문자열이 string.Empty와 같아도 ArgumentNullException을 던질 수 있습니까? 기술적으로 그것은 null이 아니기 때문입니다. ArgumentNullException을 던져서는 안된다고 생각한다면 어떤 예외를 throw해야합니까? 경우에는

+1

문자열이 ""인 경우 Throwing ArgumentNullException이 오해의 소지가 있습니다. –

+0

나는 이전에 이런 식으로 해본 이유가 "조 (Joe)"의 대답 때문이라고 동의합니다. 이것은 .net 프레임 워크 코드에서 이와 같이 사용됩니다. – Kepboy

답변

35

ArgumentException을 사용해야합니다. 이것은 null이 아닌 다른 문제를 나타냅니다. NullReferenceException을 피하려면 먼저 null을 확인한 다음 비어있는 대문자가 있는지 확인하고 공백이 있는지 확인하십시오.

private void SomeMethod(string someArgument) 
{ 
    if(someArgument == null) 
     throw new ArgumentNullException("someArgument"); 

    if (someArgument.Trim() == String.Empty) 
     throw new ArgumentException("Input cannot be empty", "someArgument"); 

    // do some work 
} 

.NET 4.0로서 당신은 한 번에 검사를 수행 할 수 String.IsNullOrWhiteSpace 방법을 사용할 수 있습니다. 이렇게하면 세분화 된 예외 유형을 지정하지 않아도되므로 ArgumentException을 선택하고 적절하게 메시지를 업데이트 할 수 있습니다.

+0

C# 2.0을 사용하고 있는데, InvalidArgumentException에 대한 유일한 참조는 Microsoft.SqlServer.Management.Common 네임 스페이스에 있으며, 내 자신의 InvalidArgumentException 클래스를 만드는 것이 좋습니다. – Kepboy

+0

@ 키스 : 네 말이 맞아, 내 실수 야. 프레임 워크에서 제공하는 ArgumentException을 사용하거나 자신이 원하는대로 작성할 수 있습니다. 적절한 이름을 반영하도록 수정하겠습니다. –

+3

ArgumentException 생성자는 ArgumentNullException과 같은 "paramName"매개 변수를 사용하지 않습니다. 그래서 'ArgumentException ("paramName")'을 던지면 잠재적으로 혼란 스럽습니다. 인수에 잘못된 점을 알려주지 않기 때문입니다. "message"인수를 제공해야합니다 ("someArgument는 빈 문자열이 아닐 수도 있습니다"). 국제 앱에서는이 메시지를 현지화해야합니다. 그러므로 빈 문자열 케이스와 null 케이스를 구분할 필요가있는 경우에만이 모든 문제를 해결할 것입니다. – Joe

5

빈 문자열이 메소드에 허용되는 입력이 아닌 경우 ArgumentException을 던져야합니다. 고객이 ArgumentNullException을 던지면 null 인수를 제공하지 않는 경우 고객에게 혼란을 줄 수 있습니다.

단순히 다른 사용 사례입니다. null 입력 값을 허용하지 않지만 빈 문자열을 허용하는 메서드가있을 수도 있습니다. 전체 애플리케이션에서 일관성을 유지하는 것이 중요합니다.

+0

ArgumentOutOfRangeException 라인을 따라 생각하고 있었지만 어쩌면 배열 인덱스 범위 예외에 사용되었을 수도 있습니다. – Kepboy

+0

배열 인덱스 예외의 경우 IndexOutOfRangeException이 사용됩니다. 특정 문자열 컬렉션 만 허용하도록 메서드가 문서화 된 경우에만 ArgumentOutOfRangeException을 사용해야합니다.: "abc", "def", "ghi"만 허용되는 입력). –

+0

설명해 주셔서 감사합니다. – Kepboy

1

String.IsNullOrEmpty의 경우 ArgumentNullException이 때때로 사용됩니다. 예를 들어 System.Windows.Forms.Clipboard.SetText입니다.

두 가지 경우를 구별하는 데 실제 가치가없는 한 코드에서 동일한 작업을 수행하는 것이 합리적이라고 생각합니다.

ArgumentException에서 파생 된이 예외 및 기타 예외는 일반적으로 프로그래밍 오류를 나타내므로 개발자가 문제를 진단하는 데 필요한 정보를 제공해야합니다. 개인적으로 저는 빈 문자열 인수에 대해 ArgumentNullException을 사용하면 개발자가 혼란 스러울 것이라고 생각합니다. 특히 아래 예제와 같이이 동작을 문서화하는 경우 특히 그렇습니다.

/// <summary> 
/// ... description of method ... 
/// </summary> 
/// <param name="someArgument">... description ...</param> 
/// <exception cref="ArgumentNullException">someArgument is a null reference or Empty.</exception> 
public void SomeMethod(string someArgument) 
{ 
    ... 
} 
+4

.NET Framework 코드의 최신 모범 사례에 대한 예제는 Windows Forms를 참조하지 않을 것입니다. 빨리 null을 ArgumentNullException 및 빈 ArgumentException throw합니다 File.Copy (문자열, 문자열) 카운터 예제를 찾을 수있었습니다. – dcstraw

4

내가 말한 (Joe/Ahmad Mageed) 모든 것을 고려하면, 나는 그 사건에 대한 예외를 만들 것이다.

class ArgumentNullOrEmptyException : ArgumentNullException 
+14

ArgumentException에서 파생되는 것이 더 좋지 않습니까? OOP에서 "A 또는 B"가 "A"라고 말하는 것은 옳지 않은 것처럼 보입니다. – dcstraw

+0

@dcstraw ArgumentNullException은 ArgumentException에서 파생됩니다. 이 경우에는 ArgumentNullOrEmptyException이 ArgumentNullException에서 파생 된 것이 더 좋다고 생각합니다. – Xtro

+0

또한 문자열 인수에 대해서만 의미가 있기 때문에 이름이 StringArgumentNullOrEmptyException이어야한다고 생각합니다. – Xtro

0

이것은 상황에 따라 다릅니다.

질문은 정말 잘못입니까? 그 뜻대로하면 항상 값을 기대합니까? 당신이 경우에, 여기에 다음 아마도 가장 좋은 건 아마도과 같이, 자신의 Exception을 만드는 : 등의 정보를

class StringEmptyOrNullException : Exception 
{ 
} 

당신은 또한 자신의 생성자를 추가 할 수있는 및 추가

는 그러나 수없는 경우 "예외적 인"프로그램에서 일어나는, 아마도 메서드에서 null을 반환하고 거기에서 처리하는 것이 더 나은 생각이 될 경우.다만 기억하십시오, Exception는 특별 조건을 위해이다. 이 도움이

희망,

카일

+1

자신 만의 예외를 만들면 Exception보다는 ArgumentException에서 파생됩니다. – Joe

+0

컨텍스트에 따라 실제로 컨텍스트에 따라 다릅니다. 다른 곳에서 사용하고 싶다면 좀 더 일반적인 것으로 만드십시오. 예를 들어 비어 있으면 안되는 문자열을 생성하는 메서드가 있으면 ArgumentException이 최선의 선택이 아닙니다. 따라서 사용하는 사용량과 사용되는 컨텍스트에 따라 상속 할 대상을 결정하게됩니다. –

+0

IMO는 두 가지 상황입니다 - 문자열을 생성하는 메서드와 메서드에 전달 된 인수입니다. 두 가지 예외 유형을 선호합니다. 여러 가지 종류의 오류 상황을 단일 예외로 잼하는 것보다 자세한 정보를 얻는 것이 좋습니다. –

0

왜이 코드를 사용하지 않는?

private void SomeMethod(string someArgument) 
{ 
//chek only NULL 
if(ReferenceEquals(someArgument,null)) 
    throw new ArgumentNullException("someArgument"); 

// and after trim and check 
if (someArgument.Trim() == String.Empty) 
    throw new ArgumentException("Input cannot be empty", "someArgument"); 

// do some work 
} 
관련 문제