업데이트 : Visual Studio 2015부터 C # 컴파일러 (언어 버전 6)가 이제 ?.
연산자를 인식하여 "깊은 null 검사"가 쉬워집니다. 자세한 내용은 이 답변 을 참조하십시오.
이 삭제 된 답변이 제안한 것처럼 코드를 다시 디자인하는 것 외에도
다른 (아마도 끔찍한) 옵션은 try…catch
블록을 사용하여 NullReferenceException
깊은 속성 조회 중에 발생하는 경우를 확인하는 것입니다.
try
{
var x = cake.frosting.berries.loader;
...
}
catch (NullReferenceException ex)
{
// either one of cake, frosting, or berries was null
...
}
나는 개인적으로 다음과 같은 이유로 이것을하지 않을 것입니다 :
- 멋져 보이지 않습니다.
- 예외 처리를 사용합니다. 예외 처리는 정상적인 상황에서 자주 발생할 것으로 예상되는 예외 상황이 아니라 예외적 인 상황을 대상으로해야합니다.
NullReferenceException
아마도 명시 적으로 잡히지 않아야합니다. ( 이 질문을 참조하십시오 .)
일부 확장 방법을 사용하는 것이 가능합니까 아니면 언어 기능 일 것입니다 ...]
C #이 이미 좀 더 정교한 게으른 평가를 갖지 않았거나 리플렉션을 사용하지 않는 한 (언어가 아닌 다른 언어 기능이 C # 6에서 .?
and ?[]
연산자 형식으로 제공 될 수 있음) 거의 확실 합니다. 성능 및 형식 안전상의 이유로 좋은 아이디어).
단순히 cake.frosting.berries.loader
함수에 전달 하는 방법이 없기 때문에 (평가되고 null 참조 예외가 발생 함) 다음과 같은 방법으로 일반 조회 메소드를 구현해야합니다. 찾다:
static object LookupProperty( object startingPoint, params string[] lookupChain )
{
// 1. if 'startingPoint' is null, return null, or throw an exception.
// 2. recursively look up one property/field after the other from 'lookupChain',
// using reflection.
// 3. if one lookup is not possible, return null, or throw an exception.
// 3. return the last property/field's value.
}
...
var x = LookupProperty( cake, "frosting", "berries", "loader" );
(참고 : 코드가 편집되었습니다.)
이러한 접근 방식에는 몇 가지 문제점이 있습니다. 첫째, 어떤 유형의 안전성과 간단한 유형의 속성 값 상자를 얻을 수 없습니다. 둘째, 문제가 발생하면 돌아올 수 있으며 null
호출 함수에서이를 확인하거나 예외를 throw해야하며 시작한 곳으로 돌아갑니다. 셋째, 느려질 수 있습니다. 넷째, 처음 시작한 것보다 더 나빠 보입니다.
[...] 아니면 나쁜 생각입니까?
나는 함께 머물 것입니다 :
if (cake != null && cake.frosting != null && ...) ...
또는 Mehrdad Afshari의 위 답변으로 이동하십시오.
추신 : 이 답변을 썼을 때, 나는 분명히 람다 함수의 표현 트리를 고려하지 않았습니다. 이 방향의 솔루션에 대한 예는 @driis의 답변을 참조하십시오. 또한 일종의 리플렉션을 기반으로하므로 간단한 솔루션 ( if (… != null & … != null) …
) 뿐만 아니라 성능도 좋지 않을 수도 있지만 구문 관점에서 더 잘 판단 될 수 있습니다.