람다 식에서 null 전파 연산자를 사용할 수없는 이유는 무엇입니까?


102

나는 종종 더 읽기 쉬운 코드를 제공하기 때문에 내 코드에서 null 전파 연산자를 사용합니다. 특히 긴 쿼리에서는 사용되는 모든 단일 클래스를 null 검사 할 필요가 없습니다.

다음 코드는 람다에서 null 전파 연산자를 사용할 수 없다는 컴파일 오류를 발생시킵니다.

var cnt = humans.AsQueryable().Count(a => a.House?[0].Price == 5000);

오류 :

오류 CS8072 식 트리 람다에 null 전파 연산자가 포함될 수 없습니다.

C #은 정말로 다른 것을 할 수 없다면 위의 코드를 다음 코드로 쉽게 변환 할 수 있습니다!

var cnt = humans.AsQueryable().Count(a => a.House != null && a.House[0].Price == 5000);

왜 C #이 아무 일도하지 않고 컴파일러 오류를 던지는 이유가 궁금합니다.


4
Foo?.Bar일치하지 않는 Foo != null ? Foo.Bar : null때문에 Foo번역이 모든 경우에 정확하지 않을 것이다, 그래서 조건부로 두 번 널 전파 연산자를 사용하여 한 번 평가하고있다.
Lucas Trzesniewski

3
EF에 대한 코드의 경우 쿼리가 SQL 호출로 변환 될 때 SQL이 널을 던지지 않기 때문에 널 전파 연산자가 실제로 필요하지 않을 가능성이 있습니다. :-)
xanatos

NB : EF는 현재 연산자를 지원하지 않기 때문에 쓰는 var q = from c in Categories join p in Products on c equals p.Category into ps from p in ps.DefaultIfEmpty() select new { Category = c, ProductName = (p?.ProductName)??"(No products)"};대신 쓰는 것이 유용 할 것입니다 . ProductName = (p == null) ? "(No products)" : p.ProductName?.
Matt

답변:


72

식 트리 람다 (대리자 람다와 달리)는 아직 null 전파를 지원하지 않는 기존 LINQ 공급자에 의해 해석되기 때문에 복잡합니다.

조건식으로 변환하는 것이 항상 정확한 것은 아닙니다 ?.. 예를 들어 단일 평가 만있는 동안 여러 평가가 있기 때문입니다.

customer.Where(a => c.Increment()?.Name) // Written by the user 
customer.Where(a => c.Increment() == null ? null : c.Increment().Name) // Incorrectly interpreted by an old LINQ provider

3 가지 솔루션이 제공되는 CodePlex 에 대한 관련 토론에서 더 깊이 들어갈 수 있습니다 : NullPropagationExpression, ConditionalExpression& a hybrid


23
특정 쿼리 공급자가이를 지원할 수 없다고해도 놀라지 않을 것입니다.하지만 이것이 C # 언어가 지원하지 않는 이유는 아닙니다.
Servy 2015 년

16
사실 특정 쿼리 공급자가 아직 없습니다 이를 지원은 금지하는 이유가 아닌 모두 에서 쿼리 공급자를 지금까지 사용 할 수있는.
Servy 2015 년

10
그리고 분명히 쿼리 공급자는 해당 공급자의 사용자가 실제로이를 나타내는 표현식 트리를 만들 수있을 때까지 이러한 요청을 처리하는 데 시간을 할애하지 않을 것입니다. 이를 지원하려면 먼저 람다가이를 나타낼 수 있어야합니다. 후에 그 존재, 쿼리 제공 업체는 수 시작 그들이 적절하다고 생각, 그것은을 지원합니다. 또한 모든 종류의 다른 일을하는 많은 공급자가 있습니다. EF가 세계에서 유일한 쿼리 공급자 인 것과는 다릅니다.
Servy 2015 년

7
요점Expression모든 C # 표현식을 의미 론적으로 코드로 표현할 수 있다는 것입니다. 언어의 일부에 불과하도록 설계되지 않았습니다.
Servy 2011 년

6
이 문제는 3 년 후에도 여전히 해결되지 않은 것 같습니다. Microsoft가 지금까지 시간을 찾을 수 없었어야하나요? 그들은 요즘 C #에서 새로운 기능을 절반으로 구현하기위한 변명으로 시간과 자원을 사용하는 나쁜 습관을 가지고있는 것 같습니다.
NetMage
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.