Po przeczytaniu tego pytania na temat HNQ, zacząłem czytać o Nullable Reference Type w C # 8 i przeprowadziłem kilka eksperymentów.
Mam świadomość, że 9 razy na 10, a nawet częściej, gdy ktoś mówi: „Znalazłem błąd kompilatora!” dzieje się tak zgodnie z projektem i własnym nieporozumieniem. A ponieważ zacząłem przyglądać się tej funkcji dopiero dzisiaj, najwyraźniej nie bardzo dobrze ją rozumiem. W ten sposób, spójrzmy na ten kod:
#nullable enable
class Program
{
static void Main()
{
var s = "";
var b = s == null; // If you comment this line out, the warning on the line below disappears
var i = s.Length; // warning CS8602: Dereference of a possibly null reference
}
}
Po przeczytaniu dokumentacji, do której się powiodłem, spodziewałbym się, że s == null
linia ostrzeże mnie - w końcu s
wyraźnie nie można jej zerwać, więc porównywanie jej z null
tym nie ma sensu.
Zamiast tego otrzymuję ostrzeżenie w następnym wierszu, a ostrzeżenie mówi, że s
możliwe jest odwołanie zerowe, chociaż dla człowieka jest oczywiste, że tak nie jest.
Ponad to, ostrzeżenie jest nie wyświetlany jeśli nie porównać s
do null
.
Zrobiłem trochę googlingu i natknąłem się na problem GitHub , który okazał się dotyczyć czegoś zupełnie innego, ale w trakcie tego procesu przeprowadziłem rozmowę z współpracownikiem, która dała więcej wglądu w to zachowanie (np. „Czeki zerowe są często użytecznym sposobem mówiąca kompilatorowi, aby zresetował swoje wcześniejsze wnioskowanie na temat dopuszczalności zmiennej. ” ). Pozostało mi jednak główne pytanie bez odpowiedzi.
Zamiast tworzyć nowy problem na GitHub i potencjalnie zajmować czas niewiarygodnie zajętym współpracownikom projektu, udostępniam to społeczności.
Czy możesz mi wyjaśnić, co się dzieje i dlaczego? W szczególności dlaczego nie generuje się żadnych ostrzeżeń na s == null
linii i dlaczego mamy, CS8602
skoro nie wydaje się, że null
możliwe jest odniesienie? Jeśli wnioskowanie o zerowanie nie jest kuloodporne, jak sugeruje połączony wątek GitHub, jak może pójść nie tak? Jakie byłyby tego przykłady?
?
ponieważ s
nie ma wartości zerowej. Nie staje się zerowalne, po prostu dlatego, że byliśmy wystarczająco głupi, aby go porównać null
.