2017-10-23 15 views
3

link here.왜 string.Format이 ArgumentNullException을 throw하지 않습니까? 형식은 (꽤 합리적인) null의 경우 MSDN 및 String.format에 따르면

을 던졌습니다하지만 테스트는 단지 두 번째 인수뿐만 아니라 null의 경우, 두 번째가 채워져 있지 않은 경우 것을 수행했다.

하는 던져하지 않습니다 다음

string test = string.Format(null, "string"); 

다음 발생을 첫 번째 매개 변수에 대해 불평 (형식) :

string test = string.Format(null, null); 

JustDecompile 소스 코드와 함께 학습과 파고는 다음과 같은 방법을 호출

private static string FormatHelper(IFormatProvider provider, string format, ParamsArray args) 
{ 
    if (format == null) 
    { 
     throw new ArgumentNullException("format"); 
    } 
    return StringBuilderCache.GetStringAndRelease(StringBuilderCache.Acquire(format.Length + args.Length * 8).AppendFormatHelper(provider, format, args)); 
} 

형식으로는 의미가 없으며 예외는 없습니다. 던져. 어떤 힌트?

답변

9

아, 과부하 해결의 즐거움. 이 경우 실질적으로 string.Format(IFormatProvider, string, params object[])을 호출하고 있으므로 provider 매개 변수에 대해 null 인수를 전달합니다. 이는 전적으로 유효하며 현재 culture를 사용한다는 의미입니다.

두 번째 인수를 문자열 리터럴에서 string으로 변환하는 것이 문자열 리터럴에서 object으로 변환하는 것보다 좋기 때문에 오버로드가 "더 좋습니다". 당신이 바로 과부하를 강제로 인수 이름을 사용하는 경우

이로드 : 예상대로

string text = string.Format(format: null, arg0: "string"); 

은 ... 다음은 예외가 발생합니다.

+0

이 때문에 나는'null '대신에 메소드 인자에'default (T)'를 전달하는 습관을 갖기 위해 노력했다. 널 (null)을 전달할 때 올바른 메소드에 바인드하더라도 사용자가 코드를 손상시키는 과부하를 도입하지 않는다고 보장 할 수는 없습니다. 더 나쁜 것은 얼마 동안 그것을 깨닫지 못할 수도 있습니다. –

+0

이것이 과장된 악취입니다. 사람들이 FormatByProvider와 같은 메서드 이름을 한정하도록합니다. 당신은 당신 자신의 메소드 이름에서 언제나 그렇게 할 수 있습니다. 예, 코드가 더 길어집니다. 그리고 사람들은이 쓰레기라고 부를 것입니다. 유닛 테스트는 코드를 너무 길게 만들고, 사람들은 그 코드가 속임수라고 말하는 것을 보지 못합니다. – FastAl

+0

놀라운. 고마워. 존. –