Lambda ifadelerinde neden boş yayılma operatörünü kullanamıyorum?


104

Genellikle kodumda boş yayma operatörü kullanırım çünkü bana daha okunabilir kod verir, özellikle uzun sorgularda kullanılan her bir sınıfı null-kontrol etmem gerekmiyor.

Aşağıdaki kod, lambda'da null propagating operatörü kullanamayacağımız bir derleme hatası atar.

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

Hata :

Hata CS8072 Bir ifade ağacı lambda boş yayılma operatörü içermeyebilir.

C # Gerçekten başka bir şey yapamıyorsanız, yukarıdaki kodu aşağıdaki koda kolayca çevirebilir!

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

C # 'ın neden hiçbir şey yapmadığını ve sadece bir derleyici hatası attığını merak ediyorum?


4
Foo?.Bareşdeğer değildir Foo != null ? Foo.Bar : nullçünkü Fooçeviri her durumda doğru olmaz böylece, koşullu iki kez boş yayılan operatör ile bir kez değerlendirilir ve böyle.
Lucas Trzesniewski

3
EF için kodu varsa, boş yayma operatörüne gerçekten ihtiyaç
duymama

Not: EF şu anda operatörü desteklemediğinden, 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)"};yazmak zorunda kalmak yerine yazmak da yararlı olacaktır . ProductName = (p == null) ? "(No products)" : p.ProductName?.
Matt

Yanıtlar:


74

İfade ağacı lambdaları (temsilci lambdaların aksine), henüz boş yaymayı desteklemeyen zaten var olan LINQ sağlayıcıları tarafından yorumlandığı için karmaşıktır.

Koşullu ifadeye dönüştürmek, birden fazla değerlendirme varken, ?.yalnızca tek bir değerlendirme varken, her zaman doğru değildir :

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

Alakalı daha derine gidebilir Codeplex üzerinde tartışma 3 çözümler sunulmaktadır: NullPropagationExpression, ConditionalExpression& melez


26
Bazı sorgu sağlayıcıları bunu destekleyemezse kesinlikle şaşırmam, ancak bu C # dilinin desteklememesi için bir neden değil.
Servy

18
Aslında bazı sorgu sağlayıcıları henüz yok bunu destekleyecek yasaklamak bir neden değildir , tüm sorgu sağlayıcıları hiç kullanmak mümkün.
2015 20

11
Ve açıkçası hiçbir sorgu sağlayıcısı, bu sağlayıcının kullanıcıları gerçekten onu temsil eden ifade ağaçları yaratabilene kadar bu tür bir talebin işlenmesini desteklemek için zaman ayırmayacaktır. Bunun desteklenebilmesi için olması gereken ilk şey lambdaların onu temsil edebilmesidir. Bundan sonra , sorgu sağlayıcıları uygun olduğunu düşündükleri için onu desteklemeye başlayabilir . Ayrıca, her türden farklı şeyler yapan birçok sağlayıcı var. EF, dünyadaki tek sorgu sağlayıcısı değil.
Servy

8
Bütün mesele , Expressiontüm C # ifadelerini anlamsal olarak kod olarak gösterebilmektir. Dilin yalnızca küçük bir alt kümesi olarak tasarlanmamıştır.
Servy

7
Görünüşe göre bu 3 yıl sonra hala çözülmedi - Microsoft şimdiye kadar saati bulamamış mıydı? Bu günlerde C #'daki yeni özellikleri yarıya indirmek için zamanı ve kaynakları bir bahane olarak kullanma konusunda kötü bir alışkanlığa sahip gibi görünüyorlar.
NetMage
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.