Một loại tham chiếu không nullable trong C # 8 có thể là null trong thời gian chạy không?


10

Dường như với tôi thực sự không có gì đảm bảo rằng một biến không có giá trị sẽ không có giá trị. Hãy tưởng tượng tôi có một lớp có một thuộc tính không thể rỗng:

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

Bây giờ có vẻ như bây giờ không thể là null. Nhưng nếu chúng ta tham chiếu lớp này với một thư viện khác không sử dụng ngữ cảnh nullable, không có gì ngăn nó gửi null trong đó.

Điều đó có đúng không hoặc có một số kiểm tra thời gian chạy có lẽ cũng đảm bảo điều này?


Là nó public void Foo(string test){...}hay public Foo(string test){...}?
huMpty duMpty

Cảm ơn, tôi đã sửa nó. Đó là những gì xảy ra khi con người phụ thuộc quá nhiều vào R # để tạo ra các nhà xây dựng :)
Ilya Chernomordik

2
C # 9 sẽ (có khả năng) thêm xác nhận null đơn giản hóa .
Steven

Nói tóm lại, tính năng "loại tham chiếu nullable" bị hỏng hoàn toàn.
Alejandro

Câu trả lời:


9

Đây là những gì MS nói về ( https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/upTHER-to-nullable-references#interfaces-with-external-code ):

Trình biên dịch không thể xác thực tất cả các cuộc gọi đến API công khai của bạn, ngay cả khi mã của bạn được biên dịch với bối cảnh chú thích không thể kích hoạt được bật. Hơn nữa, các thư viện của bạn có thể được sử dụng bởi các dự án chưa chọn sử dụng các loại tham chiếu không thể sử dụng được. Xác thực các đầu vào cho các API công khai mặc dù bạn đã khai báo chúng là các loại không thể hoàn thành.


2

ai đó luôn có thể làm

var myFoo = new Foo(null);

Có thể bạn có thể sử dụng Thiết kế hướng tên miền

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

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

Vâng, bạn nói đúng, dù sao tôi cũng chỉ là một cảnh báo. Tôi hy vọng trong tương lai họ thực sự có thể thực thi nó bằng cách nào đó như trong ví dụ như Kotlin
Ilya Chernomordik

2

Bạn đã đúng, mã khác không sử dụng tính năng mới có thể gán null cho thuộc tính này, không có kiểm tra thời gian chạy, nó chỉ là gợi ý trình duyệt.

Bạn luôn có thể tự làm điều đó nếu bạn muốn kiểm tra thời gian chạy:

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

Lưu ý rằng bạn có thể đảm bảo không có giá trị trong hầu hết mã của mình, bạn chỉ cần thêm các bộ bảo vệ vào API công khai cấp cao nhất của mình và đảm bảo các lớp được niêm phong thích hợp, v.v.

Tất nhiên mọi người vẫn có thể sử dụng sự phản chiếu để f *** mã của bạn lên, nhưng sau đó nó vào chúng


Vì vậy, điều này có nghĩa là tôi vẫn có thể có được Ngoại lệ tham chiếu Null mặc dù tôi sử dụng loại không nullable, phải không?
Ilya Chernomordik

Chà .... bạn không thể trong mã bạn biên dịch, vì bạn có gợi ý về ... nhưng mã người khác không có gợi ý, nhưng tham khảo mã của bạn - vâng họ có thể có ngoại lệ null
Milney

Chà, nếu ví dụ, một máy tự động sử dụng công cụ xây dựng của bạn, hoặc một cái gì đó tương tự, thì vẫn là bạn, người sẽ có ngoại lệ :)
Ilya Chernomordik

Of course people can still use reflection to f*** your code up, đúng, đúng thật. Bạn chắc chắn có thể sử dụng sự phản chiếu để làm điều này, nó được khuyến khích , không , mọi người vẫn làm nó, vâng.
Çöđěxěŕ

2

Ngay cả trong mã của riêng bạn, nếu bạn chọn làm như vậy, bạn có thể vượt qua null, sử dụng toán tử tha thứ null. null!được coi là không có giá trị cho đến khi phân tích tính vô hiệu của trình biên dịch có liên quan.


-1

Để đối phó với kiểm tra null và cũng làm cho mã của bạn có thể đọc được, tôi đề xuất mẫu Null Object Design.

Đọc thêm tại đây:

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

Về cơ bản, nó liên quan đến việc tạo một đối tượng mới có nguồn gốc từ cùng một giao diện và có thể hiện null.

Thí dụ:

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()  
    { }  
}  

Không thể tránh được Nulls, tuy nhiên chúng có thể được kiểm tra sạch sẽ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.