ORM ile DTO sınıfları kullanılırken C # 8'deki boş değerli başvuru türü


9

Bu özelliği, aşağıda verildiği gibi, veri aktarım nesnesi (DTO) sınıflarına sahip bir projede etkinleştirdim:

public class Connection
    {
        public string ServiceUrl { get; set; }
        public string? UserName { get; set; }
        public string? Password { get; set; }
        //... others 
    }

Ama hatayı alıyorum:

CS8618: Null değeri olmayan 'ServiceUrl' özelliği başlatılmadı. Mülkü boş olarak bildirmeyi düşünün.

Bu bir DTO sınıfı, bu yüzden özellikleri başlatmıyorum. Bu özelliklerin null olmadığından emin olmak için sınıfı başlatan kodun sorumluluğu olacaktır.

Örneğin, arayan şunları yapabilir:

var connection = new Connection
{
  ServiceUrl=some_value,
  //...
}

Benim sorum: C # 8'in nullability bağlamı etkinleştirildiğinde DTO sınıflarında bu tür hatalar nasıl ele alınır?


3
Yapım başlatma işlemini gösterdiğiniz şekilde yaptığınızda, varsayılan yapıcı çalışır (ServiceUrl öğesini varsayılan değerine (dizeler için null) ilklendirir). Sonra, initialize deyimi çalışır.
Sıfırlanamaz

POCO, yapıcısı olmadığı veya özelliklerin başlatılmadığı anlamına gelmez. Bu demektir Plain Old C# Object. Herhangi bir özel sınıftan miras almadan başka herhangi bir nesne gibi. Farklı bir sorunuz olduğundan şüpheleniyorum . DTOs nasıl oluşturulur -Data Transfer Objects
Panagiotis Kanavos

This should be the responsibility of the one initializing the class to ensure that the properties are non-nullsınıf her zaman geçerli bir durumda olmalıdır. Eğer nullizin verilmez, mülkiyet gerektiğini asla boş. Belki de, temel bir dize yerine, URL için NoneF # seçeneğindeki Option sınıfı gibi veya "Eksik" değerine sahip özel bir sınıf kullanmalısınız . C # 8, bu sınıfları yazmanıza ve desen eşleşmesi ile kontrol etmenize izin verir
Panagiotis Kanavos

@Panagiotis Kanavos, Sınıf, benim durumumda, parametresiz Yapıcı olmak için bir kısıtlamaya sahiptir. Yani Mülkiyet Initializer kullanmak zorunda: public string ServiceUrl { get; set; } = default! ;. Umarım Roslyn gelecekte Geç başlatmayı ctor kapsamı dışında ele almanın bir yoluna sahip olabilir. MayBe <T> (Option sınıfı gibi) kullanıyordum, ancak yeni kod için c # 8'de nulllable Reference Type'a geçtim.
M.Hassan

NRT'ler Maybes değil, aslında Maybes artık daha da önemli ve kullanımı daha kolay. Tabii ki, desen eşleştirme ile çalışmayı kolaylaştıran C # deyimleri kullanarak inşa ediliyorlar
Panagiotis Kanavos

Yanıtlar:


12

Bir sonraki çözüm EF Core & EF6 tarafından önerilmektedir bkz.

1) null!Affetme operatörü ile başlayarak

public string ServiceUrl { get; set; } = null! ;
//or
public string ServiceUrl { get; set; } = default! ;

2) Destek alanını kullanma:

        private string _ServiceUrl;
        public string ServiceUrl
        {
            set => _ServiceUrl = value;
            get => _ServiceUrl
                   ?? throw new InvalidOperationException("Uninitialized property: " + nameof(ServiceUrl));
        }


Soru, !operatörü kullanamayacağını belirtti .
Athanasios Kataras

Kullanamıyorum! yazın, ancak bahsettiğim bağlantı null! Bu geçici bir çözümdür. Soruyu değiştirdim.
M.Hassan

" null! ", C # 8'e eklenen (boş bir bağışlayıcı) operatördür . Doğru bir belge referansı docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Alex Klaus

Keşke sadece dize yazabilseydim! string yerine .. {get; Ayarlamak; } = null !, bu çok tekrarlanıyor .... ya da sadece sınıf dışı özelliklerinin boş bırakılması bekleniyor işaretleyin ..
Peter

8

Null değerine sahip değilse, nesne başlatıldığında derleyici ne yapabilir?

Dizenin varsayılan değeri null olduğundan,

  1. ya bildirimde dize varsayılan değeri atamanız gerekir

    public string ServiceUrl { get; set; } = String.Empty;

  2. Veya uyarıdan kurtulmanız için varsayılan kurucudaki değeri başlatın

  3. !Operatörü kullanın (kullanamayacağınız)

  4. Belirtilen robbpriestley gibi nullable olun.


4
Ya da hizmet URL'sini nullable olmayan bir dize olarak kabul eden bir kurucu ekleyin.
Jon Skeet

ServiceUrl'can't olamaz = String.Empty. Null olamaz karmaşık tür diğer Özellikleri vardır, bu yüzden defaultgibi kullanılır : 'public MyClass MyProperty {get; Ayarlamak; } = varsayılan! 'uyarısını durdurun. Bu sınıf (ve diğerleri) parametresiz yapıcıdır ve son zamanlarda ctor kapsamı dışında başlatılır.
M.Hassan

1

Bazı senaryolarda kullanışlı olabilecek başka bir şey:

[SuppressMessage("Compiler", "CS8618")]

Elemanın üstünde veya tam tipte kullanılabilir.


Dikkate alınacak başka bir şey de #nullable disable, tüm dosya için nullable referansını devre dışı bırakmak için dosyanın üstüne eklemektir .

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.