Mam pytanie dotyczące Odnienny system Rodzaju odniesienia Dostępne od C # 8.
Przypuśćmy, że mamy klasę modelu domeny C # z uznanym właściwością typu odniesienia jak poniżej:
public class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
}
Do tej pory nie ma problemu. Ale uważam, że scenariusz prawdziwych światów, często chcę sprawdzić ważność nieruchomości, ponieważ jest to publiczna mutowalna nieruchomość i muszę upewnić się, że model niezmienny, gdy zmienia się nieruchomość.
public class Person
{
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException("Name is required.");
}
public Person(string name)
{
Name = name;
}
}
Następnie kompilator generuje ostrzeżenie CS8618, w zasadzie mówienie
"Non Nulable Field Name nie jest zainicjowany. Rozważ deklaruj pole jako nieważny typ".
Tak więc za każdym razem, gdy spotykam ostrzeżenie, że muszę załączyć konstruktora z następującą dyrektywą Pragma.
#pragma warning disable CS8618
public Person(string name)
{
Name = name;
}
#pragma warning restore CS8618
Ale myślę, że jest zbędny i nudny, aby zawsze to zrobić. Czy mogę coś nadużywać, czy jest lepszy sposób na napisanie takiej nieruchomości bez ostrzeżenia?
Oczywiście mogę zmienić typ właściwości na string?
jako kompilator sugeruje, ale pojęcznie nie jest to akceptowalne jako rozwiązanie, ponieważ osoba powinna zawsze mieć nazwa bez Null i chcemy wyraźnie wyraźnie w stosunku do takiego niezmiennego stanu w klasie domeny.
Innym rozwiązaniem, które rozważałem, jest upuścić logikę walidacji argumentu i po prostu poleganie na nieważnym ostrzeżeniu kompilatora, ale nie zawsze jest to możliwe (mam na myśli często walidację innego niż kontrola NULL jest również wymagana.) Wymagane jest tylko ostrzeżenie w regularnych ustawieniach projektu, więc Nie sądzę, że to dobre rozwiązanie.
2 odpowiedzi
Na razie możesz uniknąć tego ostrzeżenia, inicjując pole _name
za pomocą wartości domyślnej z Null-wybaczający operator !
, jak
private string _name = default!;
Lub
private string _name = null!;
Istnieje również otwarty Wydanie GitHub dla tego.
Możesz również zadeklarować _name
jako string?
i określić, że wartość powrotna Name
właściwości nie może być null
(Nawet jeśli string?
Pozwala na to), Korzystanie z {{X5 }} atrybut
private string? _name;
[NotNull]
public string? Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException("Name is required.");
}
Powinno być w porządku, w przeciwnym razie kompilator pokazuje ostrzeżenie przed logiką walidacyjnej odbędzie się w seter
set => _name = value ?? throw new ArgumentNullException("Name is required.");
Rozważmy następujący kod
var person = new Person(null);
W tym przypadku dostaniesz
OSTRZEŻENIE CS8625: Nie można konwertować null dosłownego do nieważnego typu odniesienia.
Przed ArgumentNullException
zostanie rzucony.
Jeśli ustawisz <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
lub traktuj CS8625
ostrzeżenie jako błąd, wyjątek nie zostanie rzucony
Na podstawie To:
Ostrzeżenia dotyczące zainicjowanych pól Q: Dlaczego ostrzeżenia zgłaszane są dla dziedzin, które są inicjalizowane pośrednio przez konstruktora lub na zewnątrz konstruktora?
Odp.: Kompilator rozpoznaje pola wyraźnie wyraźnie przydzielone tylko w obecnym konstruktorze, a ostrzega dla innych dziedzin zadeklarowanych jako nieuznane. To ignoruje inne sposoby, w jaki pola mogą być inicjowane, takie jak metody fabryczne, metody pomocnicze, osadniki nieruchomości i inicjalizatory obiektów. Będziemy zbadać rozpoznawanie wspólnych wzorców inicjalizacji, aby uniknąć niepotrzebnych ostrzeżeń.
Więc z tym powiedziano na razie przenoszenie zadania bezpośrednio do konstruktora, jest jedynym możliwym sposobem. I na pewno korzystanie z dyrektywy Pragma wydaje się w porządku dla tego IMO.
Podobne pytania
Powiązane pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.