ประเภทอ้างอิงที่ไม่เป็นโมฆะใน C # 8 สามารถเป็นโมฆะในรันไทม์หรือไม่


10

ดูเหมือนว่าสำหรับฉันไม่มีการรับประกันว่าตัวแปรที่ไม่เป็นโมฆะจะไม่มีโมฆะ ลองนึกภาพฉันมีชั้นเรียนที่มีคุณสมบัติหนึ่งที่ไม่เป็นโมฆะ:

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

ตอนนี้อาจดูเหมือนว่าตอนนี้ไม่สามารถเป็นค่าว่างได้ แต่ถ้าเราอ้างอิงคลาสนี้กับไลบรารี่อื่นที่ไม่ได้ใช้บริบทที่ไม่มีค่าใด ๆ จะไม่มีสิ่งใดหยุดมันจากการส่งค่า null ในนั้น

ถูกต้องหรือมีการตรวจสอบรันไทม์บางอย่างเช่นกันซึ่งอาจทำให้แน่ใจได้


มันเป็นpublic void Foo(string test){...}หรือpublic Foo(string test){...}?
huMpty duMpty

ขอบคุณฉันได้แก้ไขแล้ว นั่นคือสิ่งที่เกิดขึ้นเมื่อคนอาศัยมากเกินไปใน R # เพื่อสร้างก่อสร้าง :)
Ilya Chernomordik

2
C # 9 จะ (น่าจะ) เพิ่มการตรวจสอบ null ง่าย
Steven

กล่าวโดยย่อคุณลักษณะ "ประเภทการอ้างอิงที่เป็นโมฆะ" นั้นใช้งานไม่ได้
Alejandro

คำตอบ:


9

นี่คือสิ่งที่ MS กล่าวเกี่ยวกับ ( https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/upgrade-to-nullable-references#interfaces-with-external-code ):

คอมไพเลอร์ไม่สามารถตรวจสอบการโทรทั้งหมดไปยัง API สาธารณะของคุณได้แม้ว่ารหัสของคุณจะถูกคอมไพล์ด้วยบริบทหมายเหตุประกอบที่เปิดใช้งานได้ นอกจากนี้ไลบรารีของคุณอาจถูกใช้โดยโครงการที่ยังไม่ได้เลือกใช้ประเภทการอ้างอิงที่ไม่มีค่า ตรวจสอบอินพุตให้กับ API สาธารณะแม้ว่าคุณจะประกาศว่าเป็นประเภทที่ไม่สามารถลบได้


2

บางคนสามารถทำได้

var myFoo = new Foo(null);

อาจเป็นได้ว่าคุณสามารถใช้การออกแบบการขับเคลื่อนโดเมน

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

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

ใช่คุณพูดถูกมันแค่เตือนอยู่ดี ฉันหวังว่าในอนาคตพวกเขาสามารถบังคับใช้มันได้เช่นเดียวกับใน Kotlin
Ilya Chernomordik

2

คุณถูกต้องรหัสอื่น ๆ ที่ไม่ได้ใช้คุณสมบัติใหม่สามารถกำหนด null ให้กับคุณสมบัตินี้ไม่มีการตรวจสอบเวลาทำงานมันเป็นเพียงคำแนะนำ complier

คุณสามารถทำด้วยตัวเองได้เสมอหากคุณต้องการตรวจสอบรันไทม์:

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

โปรดทราบว่าคุณสามารถรับประกันได้ว่าจะไม่เป็นโมฆะในรหัสส่วนใหญ่ของคุณคุณเพียงแค่ต้องเพิ่มเจ้าหน้าที่รักษาความปลอดภัยให้กับ Public API ระดับบนสุดของคุณและตรวจสอบให้แน่ใจว่าคลาสถูกปิดผนึกอย่างเหมาะสมเป็นต้น

แน่นอนว่าผู้คนยังคงสามารถใช้การสะท้อนเพื่อ f *** โค้ดของคุณได้


ดังนั้นสิ่งนี้ได้อย่างมีประสิทธิภาพหมายความว่าฉันยังคงได้รับข้อยกเว้นอ้างอิง Null แม้ว่าฉันจะใช้ประเภทที่ไม่เป็นโมฆะใช่ไหม?
Ilya Chernomordik

อืม .... คุณไม่สามารถรวบรวมโค้ดได้เพราะคุณมีคำแนะนำใน ... แต่รหัสประจำตัวอื่น ๆ ที่ไม่มีคำแนะนำ แต่อ้างอิงรหัสของคุณ - ใช่พวกเขาสามารถรับข้อยกเว้น null ได้
Milney

ดีถ้าเช่น automapper ใช้ตัวสร้างของคุณหรืออะไรแบบนั้นก็ยังคุณที่จะได้รับการยกเว้น :)
Ilya Chernomordik

Of course people can still use reflection to f*** your code upจริงจริงจริง แน่นอนคุณสามารถใช้สะท้อนการทำเช่นนี้มันคือการแนะนำ , ไม่มีไม่คนก็ยังคงทำมันใช่
Çöđěxěŕ

2

แม้แต่ในรหัสของคุณเองถ้าคุณเลือกที่จะทำคุณสามารถส่งผ่านnullโดยใช้โอเปอเรเตอร์ที่ให้อภัยได้ null!จะถือว่าไม่เป็นโมฆะเท่าที่การวิเคราะห์ความถูกต้องของคอมไพเลอร์เป็นห่วง


-1

เพื่อจัดการกับการตรวจสอบ null และทำให้โค้ดของคุณอ่านได้ฉันขอแนะนำรูปแบบ Null Object Design

อ่านเพิ่มเติมได้ที่นี่:

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

โดยทั่วไปจะเกี่ยวข้องกับการสร้างวัตถุใหม่ซึ่งได้มาจากอินเทอร์เฟซเดียวกันและมีอินสแตนซ์ที่เป็นโมฆะ

ตัวอย่าง:

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

ไม่สามารถหลีกเลี่ยง Null ได้ แต่สามารถตรวจสอบได้อย่างหมดจด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.