C # 8'deki null olmayan bir başvuru türü çalışma zamanında boş olabilir mi?


10

Bana öyle geliyor ki, boş olmayan bir değişkenin hiç boş kalmayacağının garantisi yok. Sıfırlanabilir olmayan bir özelliği olan bir sınıf var düşünün:

public class Foo
{
    public Foo(string test)
    {
        Test = test;
    }
    public string Test {get;set;}
}

Bu şimdi boş olamaz gibi görünebilir. Ancak bu sınıfa nullable bağlam kullanmayan başka bir kitaplıkla başvurursak, hiçbir şey sınıfın null değerini göndermesini durduramaz.

Bu doğru mu ya da belki de bunu sağlayan bazı çalışma zamanı kontrolleri var mı?


Öyle mi public void Foo(string test){...}yoksa public Foo(string test){...}?
huMpty duMpty

Teşekkürler, düzelttim. İnsan inşaatçılar üretmek için R # 'a çok fazla
Ilya Chernomordik

2
C # 9 (büyük olasılıkla) basitleştirilmiş null doğrulama ekleyecektir .
Steven

Kısacası, "null edilebilir referans türleri" özelliği tamamen bozuldu.
Alejandro

Yanıtlar:


9

MS'in söylediği şey budur ( https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/upgrade-to-nullable-references#interfaces-with-external-code ):

Kodunuz boş değerli ek açıklama bağlamları etkinleştirilmiş olsa bile derleyici genel API'larınıza yapılan tüm aramaları doğrulayamaz. Ayrıca, kitaplıklarınız nullable başvuru türlerini kullanmayı seçmemiş projeler tarafından tüketilebilir. Herkese açık olmayan API'lar için girdileri geçersiz kılınan türler olarak bildirmiş olsanız bile doğrulayın.


2

birisi her zaman yapabilir

var myFoo = new Foo(null);

Etki Alanı Odaklı Tasarım'ı kullanabilirsiniz

public class Foo
{
    public Foo(string test)
    {
         if (string.IsNullOrWhiteSpace(test))
             throw new ArgumentNullException(nameof(test));

         Test = test;
    }
    public string Test {get;private set;}
}

Evet, haklısın, sanırım sadece bir uyarı. Umarım ileride gerçekten Kotlin gibi bir yerde zorlayabilirler
Ilya Chernomordik

2

Haklısın, yeni özelliği kullanmayan diğer kodlar bu özelliğe null atayabilir, sadece complier ipuçları olduğu için çalışma zamanı denetimi yoktur.

Bir çalışma zamanı denetimi istiyorsanız her zaman kendiniz yapabilirsiniz:

public string Test { get; set{ if (value == null) throw new ArgumentNullException() } }

Kodunuzun çoğunda boş kalmayacağınızı garanti edebileceğinizi , yalnızca üst düzey Genel API'nıza korumalar eklemeniz ve sınıfların uygun şekilde mühürlendiğinden emin olmanız gerektiğini unutmayın.

Tabii ki insanlar hala kodunuzu f *** için yansıma kullanabilirsiniz, ama sonra onlar üzerinde


Bu, etkili bir şekilde null edilemeyen tür kullanmamıza rağmen Null Reference Exception'ı alabileceğim anlamına gelir, değil mi?
Ilya Chernomordik

Eh .... Eğer kodda sen derleme olamaz size ... ipuçları var ama çünkü diğer halklar üzerinde ipuçları var, ama kodunuzu başvuru değil kod - evet onlar boş istisna alabilirsiniz
Milney

Peki, örneğin bir otomobil üreticisi kurucunuzu ya da bunun gibi bir şeyi kullanıyorsa, istisnayı alacak olan sizsiniz :)
Ilya Chernomordik

Of course people can still use reflection to f*** your code up, doğru, doğru. Bunu yapmak için kesinlikle yansımayı kullanabilirsiniz, tavsiye edilir mi , hayır , insanlar hala yapıyor mu, evet.
Çöđěxěŕ

2

Kendi kodunuzda bile, bunu yapmayı seçerseniz null, boş bağışlama işlecini kullanarak geçebilirsiniz . null!derleyicinin nullabilite analizi söz konusu olduğunda null olmadığı kabul edilir.


-1

Boş denetimlerle başa çıkmak ve kodunuzu okunabilir hale getirmek için Boş Nesne Tasarım deseni öneririm.

Burada daha fazla okuma:

https://www.c-sharpcorner.com/article/null-object-design-pattern/

Temel olarak, aynı arabirimden türetilen ve null örneğine sahip yeni bir nesne oluşturmayı içerir.

Misal:

public class NullExample : IExample  
{  
    private static NullExample _instance;  
    private NullExample()  
    { }  

    public static NullExample Instance  
    {  
        get {  
            if (_instance == null)  
                return new NullExample();  
            return _instance;  
        }  
    }  

    //do nothing methods  
    public void MethodImplementedByInterface1()  
    { }  

    public void MethodImplementedByInterface1()  
    { }  
}  

Boş değerlerden kaçınılamaz, ancak bunlar temiz bir şekilde kontrol edilebilir.

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.