2013-05-16 2 views
5

문자열에서 모든 숫자가 아닌 문자를 제거하는 문자열 클래스에 대한 간단한 확장 방법이 있습니다. 예를 들어 "(555) 215-4444"와 같은 전화 번호가 있으면 "5552154444"로 변환됩니다. 다음과 같이 보입니다 :확장 메서드에서 null 처리

public static string ToDigitsOnly(this string input) 
{ 
    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(input, String.Empty); 
} 

여기서 null 값을 처리하는 가장 효율적인 방법은 무엇일까요? 이러한 경우에 따라야 할 전형적인 패턴이 있습니까? 예를 들어 null이 전달되면 null 값을 돌려 주시겠습니까? 그것은 문자열 클래스를 확장하는 이후 여기에 null 값을 허용 할 수 있습니다 및 arguement 예외를 throw하지 않을 수도 있습니다 이후 (나는 이것을 사용하면 arguement 정말 전달 해요 ...)? 그러나 어떤 사람들은 '정상적인'방법처럼 예외를 던져야한다고 주장 할 수도 있습니다. 여기에서 사용하는 가장 좋은 방법은 무엇입니까?

감사합니다.

+1

내가 보통 같은 확장 방법을 치료하는 것이 확장을 사용할 수 있습니다. 그것은 사람들이 코드를 읽는 방법을 정리하는 단지 방법 일뿐입니다. StringFunctions.ToDigitsOnly (s)보다는 s.ToDigitsOnly()로 줄이기 때문에 예외를 던지려면 다른 곳으로 던져 넣으십시오. –

+1

null가 애플리케이션에서 유효한/예상 값이면 null을 반환합니다. 그렇지 않은 경우 예외를 throw합니다. 개인적으로 여기서 ArgumentException을 던질 것입니다. – JosephHirn

+2

보조 메모로; 당신은 Regex를 필요로하지 않습니다.'String.Join ("", input.Where (char.IsDigit))' – I4V

답변

9

당신은 적어도 놀라움의 원칙을 따를 수 : LINQ에서 구현 사용 패턴 :

public static string ToDigitsOnly(this string input) 
{ 
    if(input == null) 
      throw new ArgumentNullException("input"); 

    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(input, String.Empty); 
} 

을 당신은 proposed by Jon Skeet을 방법을 사용할 수 있습니다.

무효 확인 : 그것은 단순히에

input.ThrowIfNull("input"); 

는 또한 존은 인용, 깊이에 C#으로 Null 참조에 메소드를 호출 좋은 부분 10.2.4을 가지고 수표를 줄일 수 양심적 인 개발자로서, 귀하의 생산 방법은 항상 진행 전에 인수의 유효성을 확인해야합니다. 확장 메서드의이 기발한 기능에서 자연스럽게 발생하는 한 가지 질문은 첫 번째 인수가 null 인 경우 throw되는 예외입니다 (의도가 없다고 가정). ArgumentNullException이 일반 인수 인 것처럼 또는 이 NullReferenceException이어야합니까? 확장 메서드가 시작하는 인스턴스 메서드 인 경우 어떤 일이 발생 했습니까? 내가 전 추천 : 그것은 여전히 ​​확장 경우에도 확장을 분명히하지 않는 인수입니다.

나는이 권장 사항을 (개인적인 경험으로) 다음과 같이 표시합니다. 항상 정적 메서드에 대해 null을 확인하고 null 값에 의존하지 않는 것이 좋습니다. 예를 들어 ThrowIfNull 또는 IsNullOrEmpty 확장 메소드와 같이 메소드의 목적이 정확한 경우에만 한 가지 예외가 있습니다.

+0

LINQ 메서드는 null 매개 변수가있을 때 실제로 제공 할 수있는 출력이 거의 없습니다. 이것은 여기에 해당하지 않으므로 공정한 비교는 아닙니다. – Servy

+0

@Servy 미안하지만, 논쟁하고 싶지는 않습니다. 왜 그런가요? myString.Where (char.IsDigit)와 myString.ToDigitsOnly()의 차이점은 무엇입니까? –

1

행동을 잘 전달하면 (최종 사용자가 예상 할 수 있도록) 문제는 중요하지 않습니다.

내장 된 XML Documentation Comments을 사용하여 예상되는 동작을 전달하는 것이 좋습니다.

/// <exception cref="ArgumentNullException">argument is null.</exception> 
public string Example(string argument) 
{ 
    if (argument == null) 
     throw new ArgumentNullException(); 
    return argument.ToString(); 
} 
많은 예제

참조 MSDN 문서 :

1

가정하자 나는이 있습니다

class A 
{ 
    public void F() 
    { 
     //do stuff 
    } 
} 

것은 그때 실행하는 경우를 다음 코드는 어떻게됩니까?

A a = null; 
a.F(); 

당신은 NullReferenceException를 얻을. 그래서 나는 동등한 확장 메소드를 작성하는 적절한 방법은 다음과 같을 것이라고 말할 것이다.

class A 
{ 
} 

static class AExtensions 
{ 
    void F(this A a) 
    { 
     if (a == null) 
     { 
      throw new NullReferenceException(); 
     } 
     //do stuff 
    } 
} 

그러나 .NET에서는 이에 대해 동의하지 않습니다. .NET의 표준은 대신 ArgumentException을 던집니다. 대신 아마 그렇게하는 것이 가장 좋습니다.

+0

나는 그것을 추천하지 않을 것이다. 이 메소드는'AExtensions.F (null)'로 호출 할 수 있습니다. 'null' 매개 변수가 전달 될 때'ArgumentNullException'을 기대합니다. –

+1

@JimMischel True. 나는 그들이 적용되는 유형의 멤버 인 것처럼 시간 확장 메서드의 99 %를 처리하는 경향이 있습니다. 정적 메소드처럼 호출하는 경우는 유효하지만 특이합니다. ArgumentException을 사용하면 실제로 아무 문제가 없습니다. 나는 .NET이 그것을하고 있다면 그것은 갈 길이라고 생각한다. –

+0

'NullReferenceException'을 던지면서 발생하는 또 다른 문제점은 실제로 오류의 원인을 알려주지 않는다는 것입니다. 실제 오류는 null 매개 변수가 전달되는 호출 사이트에서 발생합니다. 만약 코드가 NRE를 던지면 (어쨌든 할 것이다), 클라이언트는 확장 메소드에 오류가 있다고 믿게된다. 클라이언트가 소스가없는 라이브러리를 사용하는 경우 특히 그렇습니다. 'ArgumentNullException'은 클라이언트에게 정확하게 * 문제가 무엇인지를 알려줍니다. –

1

심플; 문자열에 대한 다른 방법을 만들기 말 IsInValid()

공공 정적 IsInValid (문자열 s의) { 반환 (들 == 널) 부울 || (s.Length == 0); 당신이 확인하고 싶어 whereever }

사용 ... 또한

, 당신은 어디