DTO'lar için Sıfırlanabilir Referans Türlerini kullanma konusunda en iyi uygulama


20

Bir DynamoDB tablodan okuyarak doldurulmuş bir DTO var. Şu anda böyle göründüğünü söyle:

public class Item
{
    public string Id { get; set; } // PK so technically cannot be null
    public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
    public string Description { get; set; } // can be null
}

Bununla başa çıkmak için gelişen en iyi uygulamalar var mı? Dynamo SDK (ve diğerleri) ORM ile kötü oynar çünkü parametresiz olmayan bir yapıcı önlemek istiyorum.

Bana yazmak garip geliyor public string Id { get; set; } = "";çünkü bu bir PK olduğu için asla olmayacak Idve asla boş olamaz. ""Yine de bir şekilde yapsa bile ne faydası olurdu ?

Peki bununla ilgili en iyi uygulamalar var mı?

  • Bunların hepsini, string?bazıları asla olmamasına rağmen boş olabileceğini söyleyebilir miyim ?
  • Ben initialise Should Idve Namebirlikte ""onlar çünkü gerektiğini geçersiz ve bu gösterileri asla niyet olsa ""kullanılamaz asla.
  • Yukarıdaki bazı kombinasyonlar

Lütfen dikkat: bu C # 8 nullable referans türleri hakkındadır.En iyi olduklarını bilmiyorsanız cevap vermeyin.


Biraz kirli, ama sadece #pragma warning disable CS8618dosyanın üstündeki tokat .
Yirmi

7
Bunun yerine , asla etkili olmayacağını bildiğiniz bir özelliği başlatmak için = ""kullanabilirsiniz (derleyici bunu bilmenin bir yolu olmadığında). Eğer yasal olarak olabilir , bu bir beyan edilmelidir . Alternatif olarak, DTO nullabilite kontrolü yardımdan daha rahatsız edici ise, sadece bu tür için NRT'leri kapatmak için türü / içine sarmanız yeterlidir. = null!nullDescriptionnullstring?#nullable disable#nullable restore
Jeroen Mostert

@JeroenMostert Bunu bir cevap olarak koymalısınız.
Magnus

3
@Magnus: "En iyi uygulamalar" isteyen herhangi bir soruyu cevaplamak konusunda isteksizim; bu tür şeyler geniş ve özneldir. Umarım OP kendi "en iyi uygulamalarını" geliştirmek için yorumumu kullanabilir.
Jeroen Mostert

1
@ IvanGarcíaTopete: Birincil anahtar için bir dize kullanmanın olağandışı olduğunu ve koşullara bağlı olarak bile tavsiye edilemeyeceğini kabul etsem de, OP'nin veri türü seçiminin soru ile ilgisi yoktur. Bu, birincil anahtar olmayan zorunlu, null olmayan bir dize özelliğine, hatta bileşik birincil anahtarın bir parçası olan bir dize alanına da kolayca uygulanabilir ve soru yine de devam eder.
Jeremy Caney

Yanıtlar:


12

Seçenek olarak, defaultdeğişmez değeri aşağıdakilerle birlikte kullanabilirsiniz:null forgiving operator

public class Item
{
    public string Id { get; set; } = default!;
    public string Name { get; set; } = default!;
    public string Description { get; set; } = default!;
}

DTO'nuz DynamoDB'den doldurulduğundan, geçersizliği kontrol etmek için MaybeNull/NotNull koşul sonrası özelliklerini kullanabilirsiniz

  • MaybeNull Null edilemez bir dönüş değeri boş olabilir.
  • NotNull Sıfırlanabilir bir dönüş değeri hiçbir zaman boş olmaz.

Ancak bu nitelikler, yalnızca kendilerine ek açıklama eklenmiş üyelerin arayanları için geçersiz kılınan analizi etkiler. Genellikle, bu öznitelikleri yöntem döndürme, özellikler ve dizin oluşturucular alıcılara uygulayın.

Böylece, tüm özelliklerinizin boş değerli olmayan özelliklerini göz önünde bulundurabilir ve bunları MaybeNullözelliklerle dekore ederek olası nulldeğeri döndürdüğünü belirtebilirsiniz.

public class Item
{
    public string Id { get; set; } = "";
    [MaybeNull] public string Name { get; set; } = default!;
    [MaybeNull] public string Description { get; set; } = default!;
}

Aşağıdaki örnek, güncellenmiş Itemsınıfın kullanımını göstermektedir . Gördüğünüz gibi, ikinci satır uyarı göstermiyor, üçüncü satır

var item = new Item();
string id = item.Id;
string name = item.Name; //warning CS8600: Converting null literal or possible null value to non-nullable type.

Veya tüm özellikleri boş NoNulldeğerli hale getirebilir ve dönüş değerinin yapılamayacağını belirtmek için kullanabilirsiniz null( Idörneğin)

public class Item
{
    [NotNull] public string? Id { get; set; }
    public string? Name { get; set; }
    public string? Description { get; set; }
}

Uyarı, önceki örnekle aynı olacaktır.

Aynı şekilde çalışan giriş parametreleri, özellikler ve dizin oluşturucular için AllowNull/DisallowNull önkoşul özellikleri de vardır .

  • AllowNull Null edilemeyen bir girdi bağımsız değişkeni boş olabilir.
  • DisallowNull Sıfırlanabilir bir giriş argümanı asla boş olmamalıdır.

Sınıfınız veritabanından doldurulduğundan size yardımcı olacağını düşünmüyorum, ancak bunları ilk seçenek için bu şekilde özellik ayarlayıcılarının nullabilitesini kontrol etmek için kullanabilirsiniz

[MaybeNull, AllowNull] public string Description { get; set; }

Ve ikincisi için

[NotNull, DisallowNull] public string? Id { get; set; }

Post / önkoşullara ilişkin bazı yararlı ayrıntılar ve örnekler bu devblog makalesinde bulunabilir.


6

Bu senaryoda ders kitabı cevabı string?, Idmülkünüz için bir kullanmaktır , ancak aynı zamanda bu [NotNull]özelliği ile de süslemektir :

public class Item
{
  [NotNull] public string? Id { get; set; }
  public string Name { get; set; }
  public string? Description { get; set; }
}

Başvuru: Belgelere göre , [NotNull]"karşılık gelen tür izin verse bile bir çıktının boş olmadığını belirtir" özelliği.

Peki, burada tam olarak neler oluyor?

  1. İlk olarak, string?dönüş türü, derleyicinin, inşaat sırasında özelliğin başlatılmadığını ve dolayısıyla varsayılan olarak ayarlanacağını size bildirmesini engeller null.
  2. Daha sonra [NotNull]öznitelik, özelliği sıfırlanamayan bir değişkene atarken veya derleyicinin statik akış analizini uygulamada bu özelliğin asla olmayacağı konusunda bilgilendirdiğiniz için , bu özellikten vazgeçmeye çalıştığınızda bir uyarıyı engeller null.

Uyarı: C # 'ın nullability bağlamını içeren tüm vakalarda olduğu gibi, teknik olarak nullburada hala bir değer döndürmenizi ve dolayısıyla potansiyel olarak bazı aşağı yönlü istisnalar getirmenizi engelleyen hiçbir şey yoktur ; yani, kullanıma hazır çalışma zamanı doğrulaması yoktur. Tüm C # sağlayan bir derleyici uyarısıdır. Eğer tanıştırdığımda [NotNull]etkili Elinden iş mantığı hakkında bir ipucu vererek bu uyarıyı geçersiz kılma. Bu nedenle, ile bir özellik ek açıklama eklerken [NotNull], bu kararlılığınız sorumluluğunu alıyor "bu olacak asla beri gerçekleşmesi Idbir PK ve boş olamaz."

O bağlılığını korumak yardım etmek için, size olabilir ayrıca üzere tesisle açıklama isteyen [DisallowNull]özniteliği:

public class Item
{
  [NotNull, DisallowNull] public string? Id { get; set; }
  public string Name { get; set; }
  public string? Description { get; set; }
}

Başvuru: Belgelere göre , [DisallowNull]" nullkarşılık gelen tür izin verse bile, girdiye izin verilmeyeceğini belirtir" özelliği .

Değerler veritabanı aracılığıyla tahsis ediliyor beri Bu durumda alakalı olmayabilir ama [DisallowNull]hiç bir atamaya çalışırsanız nitelik size bir uyarı verecektir nulliçin (mümkün) değeri Id, bunun olabilmesi için dönüş tipi farklı şekilde izin rağmen null . Bu bağlamda, Idhareket edeceğini tam olarak bir benzeri stringise, uzak C # 'ın statik akış analizi gibi ilgilenir da değer nesnenin inşaat ve mülkiyetin nüfus arasındaki başlatılmamış kalmasına izin.

Not: Diğerlerinin de belirttiği gibi, Idvarsayılan değerlerden birini default!veya değerini atayarak da neredeyse aynı sonucu elde edebilirsiniz null!. Kuşkusuz, bu biraz üslupsal bir tercihtir. Nullabilite ek açıklamalarını daha açık oldukları ve granüler kontrol sağladıkları için kullanmayı tercih ederim, oysa !derleyiciyi kapatmanın bir yolu olarak kötüye kullanımı kolaydır . Açıkça bir değeri olan bir özelliği başlatmak da varsayılan değer olsa bile ben asla bu değeri kullanmayacağım biliyorum eğer bana nags.


-2

Dize bir referans türüdür ve her zaman geçersizdir, özel bir şey yapmanız gerekmez. Bu nesne türünü başka biriyle eşlemek istiyorsanız ancak daha sonra sorun yaşayabilirsiniz, ancak daha sonra bu sorunu çözebilirsiniz.


8
C # 8'de Nullable referans türleri hakkında konuşuyor
Magnus
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.