Często używam operatora propagującego wartość null w moim kodzie, ponieważ daje mi to bardziej czytelny kod, szczególnie w długich zapytaniach nie muszę sprawdzać wartości null każdej używanej klasy.
Poniższy kod zgłasza błąd kompilacji, którego nie możemy użyć operatora propagującego wartość null w wyrażeniu lambda.
var cnt = humans.AsQueryable().Count(a => a.House?[0].Price == 5000);
Błąd :
Błąd CS8072 Lambda drzewa wyrażeń nie może zawierać operatora propagującego wartość null.
C # Można łatwo przetłumaczyć powyższy kod na kod na następujący kod, jeśli naprawdę nie można zrobić nic innego!
var cnt = humans.AsQueryable().Count(a => a.House != null && a.House[0].Price == 5000);
Jestem ciekawy, dlaczego C # nic nie robi i po prostu zgłasza błąd kompilatora?
c#
.net
compiler-errors
c#-6.0
null-propagation-operator
Mohsen Sarkar
źródło
źródło
Foo?.Bar
nie jest równoważne z,Foo != null ? Foo.Bar : null
ponieważFoo
jest obliczane raz za pomocą operatora propagującego wartość null i dwukrotnie za pomocą warunku, więc tłumaczenie nie byłoby poprawne we wszystkich przypadkach.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)"};
zamiast pisać,ProductName = (p == null) ? "(No products)" : p.ProductName
ponieważ EF obecnie nie obsługuje?.
operatora.Odpowiedzi:
Jest to skomplikowane, ponieważ wyrażenia lambda drzewa (w przeciwieństwie do wyrażeń lambda delegatów) są interpretowane przez już istniejących dostawców LINQ, którzy jeszcze nie obsługują propagacji wartości null.
Konwersja do wyrażenia warunkowego nie zawsze jest dokładna, ponieważ istnieje wiele ocen, podczas
?.
gdy jest tylko jedna ocena, na przykład:Można pójść głębiej w odpowiedniej dyskusji na CodePlex , gdzie oferowane są 3 rozwiązania:
NullPropagationExpression
,ConditionalExpression
& hybrydąźródło
Expression
to, aby móc reprezentować wszystkie C # wyrażeń semantycznie jako kod. Nie jest to tylko mały podzbiór języka.