이것은 유효한 C # 코드입니다
var bob = "abc" + null + null + null + "123"; // abc123
유효한 C # 코드가 아닙니다.
var wtf = null.ToString(); // compiler error
첫 번째 진술이 왜 유효합니까?
답변
첫 번째 이유 :
에서 MSDN :
문자열 연결 작업에서 C # 컴파일러는 null 문자열을 빈 문자열과 동일하게 취급하지만 원래 null 문자열의 값은 변환하지 않습니다.
+ 이항 연산자 에 대한 추가 정보 :
이항 + 연산자는 하나 또는 두 피연산자가 모두 문자열 유형 인 경우 문자열 연결을 수행합니다.
문자열 연결 피연산자가 널이면 빈 문자열이 대체됩니다. 그렇지 않으면, 문자열이 아닌 인수는
ToString
유형 객체에서 상속 된 가상 메소드 를 호출하여 문자열 표현으로 변환됩니다 .을
ToString
반환null
하면 빈 문자열이 대체됩니다.
두 번째 오류의 원인은 다음과 같습니다.
null (C # 참조) -null 키워드는 개체를 참조하지 않는 null 참조를 나타내는 리터럴입니다. 참조 유형 변수의 기본값은 null입니다.
답변
+
C # 의 연산자는 내부적으로로 변환 되기 때문에 String.Concat
정적 메서드입니다. 그리고이 방법 null
은 빈 문자열처럼 취급 됩니다. String.Concat
Reflector 의 소스를 보면 다음과 같이 표시됩니다.
// while looping through the parameters
strArray[i] = (str == null) ? Empty : str;
// then concatenate that string array
(MSDN에서도 언급 함 : http://msdn.microsoft.com/en-us/library/k9c94ey1.aspx )
반면에 ToString()
인스턴스 메소드는 호출 할 수 없습니다 null
(어떤 유형을 사용해야 null
합니까?).
답변
첫 번째 샘플 은 다음과 같이 번역됩니다.
var bob = String.Concat("abc123", null, null, null, "abs123");
이 Concat
메소드는 입력을 확인하고 null을 빈 문자열로 변환합니다.
두 번째 샘플 은 다음과 같이 번역됩니다.
var wtf = ((object)null).ToString();
따라서 null
여기에 참조 예외가 생성됩니다
답변
코드의 첫 번째 부분은에서와 같이 취급됩니다 String.Concat
.
이것은 문자열을 추가 할 때 C # 컴파일러가 호출하는 것입니다. ” abc" + null
로 번역됩니다 String.Concat("abc", null)
.
내부적으로이 방법은 null
로 대체 됩니다 String.Empty
. 따라서 코드의 첫 번째 부분에서 예외가 발생하지 않습니다. 그것은 같다
var bob = "abc" + string.Empty + string.Empty + string.Empty + "123"; //abc123
그리고 ‘null’이 객체가 아니기 때문에 코드의 두 번째 부분에서 예외가 발생 합니다 .null 키워드는 객체를 참조하지 않는 null 참조를 나타내는 리터럴입니다 . 참조 유형 변수의 기본값은 null입니다.
그리고 ‘ ToString()
‘는 객체의 인스턴스에 의해 호출 될 수 있지만 리터럴은 아닙니다.
답변
.net 이전의 COM 프레임 워크에서는 문자열을 수신 한 루틴이 완료되면이를 해제 할 필요가있었습니다. 빈 문자열이 루틴으로 들어오고 나가는 것이 매우 일반적이기 때문에 널 포인터를 “해제”하려는 시도는 합법적 인 수행 작업으로 정의 되었기 때문에 Microsoft는 널 문자열 포인터가 빈 문자열을 나타내도록 결정했습니다.
COM과의 일부 호환성을 위해 .net의 많은 루틴은 null 개체를 빈 문자열로 유효한 표현으로 해석합니다. .net 및 해당 언어의 약간의 변경 (대부분 인스턴스 멤버가 “가상으로 호출하지 않음”을 표시하도록 허용 함)을 통해 Microsoft null
는 선언 된 유형 String의 개체를 빈 문자열처럼 동작하도록 만들 수있었습니다 . 만약 마이크로 소프트가 그렇게했다면, Nullable<T>
작업을 다소 다르게 Nullable<String>
해야했고 (어쨌든 IMHO가해야 할 일 을 허용하기 위해 ) 그리고 / 또는 NullableString
대체로 상호 교환이 가능 String
하지만 null
유효한 빈 문자열로.
null
그대로 a는 합법적 인 빈 문자열로 간주되고 그렇지 않은 컨텍스트 도 있습니다. 매우 유용한 상황은 아니지만 프로그래머가 알아야 할 상황입니다. 일반적으로 is 인 stringValue.someMember
경우 양식의 표현식 이 실패 하지만 매개 변수로 문자열을 허용하는 대부분의 프레임 워크 메소드 및 연산자 는 빈 문자열로 간주 됩니다.stringValue
null
null
답변
'+'
중위 연산자입니다. 다른 연산자와 마찬가지로 실제로 메서드를 호출합니다. 비-고정 버전을 상상할 수 있습니다"wow".Plus(null) == "wow"
구현자는 이와 같은 것을 결정했습니다 …
class String
{
...
String Plus(ending)
{
if(ending == null) return this;
...
}
}
그래서 .. 당신의 모범은
var bob = "abc".Plus(null).Plus(null).Plus(null).Plus("123"); // abc123
이것은 같은
var bob = "abc".Plus("123"); // abc123
어느 시점에서도 null은 문자열이되지 않습니다. 그렇게 null.ToString()
다르지 않습니다 null.VoteMyAnswer()
. 😉
답변
객체를 참조하지 않는 리터럴 이기 때문에 추측 합니다. ToString()
필요합니다 object
.