"> Nullable Reference Types در سی شارپ 8 | آموزش سی شارپ | ام اس پی سافت

Nullable Reference Types در سی شارپ ۸

Nullable Reference Types

در این مقاله، میخواهیم در مورد Nullable Reference Types در سی شارپ ۸ صحبت کنیم. تا پایان این مقاله همراه ما باشید.

Current State Of Play 

اول از همه .. انواع مرجع Nullable (باطل)؟ اما .. ما ۱۷ سال گذشته آموخته ایم که بخش عمده ای از انواع “مرجع” این است که آنها قابل قبول نیستند.

بدیهی است که این یک ساده سازی است ، اما یک برنامه نویس جوان به طور معمول به شما می گوید که “نوع ارزش” => نامعتبر است و “نوع مرجع” => ناموجود. “value type” => Not Nullable and “reference type” => Nullable.

int? nullableInt1 = null;
Nullable<int> nullableInt2 = null;
int nullableInt3 = null; //Compile error

و به یاد داشته باشید که این هماهنگی ارکان برای انواع primitive value  نیست. به عنوان مثال ، این درست کار می کند:

struct MyStruct
{

}
        
static void Main(string[] args)
{
    MyStruct? mystruct1 = null;
    MyStruct myStruct2 = null;
}

اما اکنون می خواهیم یک قطعه syntax داشته باشیم که بگوییم این باید خطای زمان کامپایل (یا هشدار) باشد؟ جالب هست.

class MyClass
{

}
        
static void Main(string[] args)
{
    MyClass myClass = null; //Acceptable by today's standards. No problem-o
}

چرا؟
بنابراین اولین سؤالی که باید پرسید این است. چرا ما به این نیاز داریم؟ برنامه ای مانند این را در نظر بگیرید:

class MyClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }
}
        
static void Main(string[] args)
{
    var myClass = new MyClass();

    //۱۰۰ lines of code. 
    myClass.SayHello();
}

نسبتا ساده است. بطور خاص ، من یک نظر برای توضیح دادن این مطلب دارم که شاید این برنامه بسیار بزرگتر از آنچه در اینجا نشان داده شده است باشد ، اما همه چیز باید خوب و نرم باشد.

اکنون بیایید بگوییم ، یک developer دیگر همراه می شود و کاری از این دست انجام می دهد:

class MyClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }
}
        
static void Main(string[] args)
{
    var myClass = new MyClass();

    //۱۰۰ lines of code. 
    if (true) //Some condition. 
    {
        myClass = null;
    }

    //۱۰۰ lines of code. 
    if(myClass == null)
    {
        //Do something special here. 
    }
    //۱۰۰ lines of code
    myClass.SayHello();
}

ممکن است در ابتدا احمقانه به نظر برسد ، اما من دیده ام که این اتفاق افتاده است.

شخصی آمده است و myClass را تنظیم کرده است تا چیزی را که در حال کار بر روی آن هستند برآورده کند.

این در عمق برنامه به خاک سپرده شده است ، و شاید در تست های آنها همه چیز خوب به نظر برسد.

اما در برخی مقطع ، ما قصد داریم یک NullReferenceException مخوف را پرتاب کنیم.

به طور طبیعی ، ما می خواهیم کاری از این دست انجام دهیم و روش تماس خود را با null check مرتبط کنیم:

static void Main(string[] args)
{
    var myClass = new MyClass();

    //۱۰۰ lines of code. 
    if (true) //Some condition. 
    {
        myClass = null;
    }

    //۱۰۰ lines of code. 
    if(myClass == null)
    {
        //Do something special here. 
    }

    //۱۰۰ lines of code. 
    if (myClass != null)
    {
        myClass.SayHello();
    }
}

اما اگر من original developer هستم ممکن است با خودم بگویم … من هرگز نخواسته ام این موضوع null باشد.

اما این بی فایده است که بگوییم من هرگز نمی خواهم چیزی از این nullشود.

همیشه احتمالاً در یک روز آن قانون را می شکنیم.

اما در همان زمان ، آیا انتظار داریم کدگذاری آنقدر دفاعی باشد که هر بار که از یک نوع مرجع استفاده می کنیم ، یک null check انجام دهیم؟

و این مشخصه اصلی از نوع مرجع nullable است.

این مربوط به کدگذاری است. من می خواهم به طور خاص بگویم “من انتظار دارم که این موضوع در بعضی موارد قابل اعتراض نباشد” یا برعکس ، به طوری که سایرdevelopers (توسعه دهندگان) ، امیدوارم در آینده در دام مرجع null قرار نگیریم.

Turning On Nullable Reference Types

همانطور که در بالا ذکر شد ، اولین مورد برای روشن کردن ویژگی Nullable Reference Types این است که باید از سی شارپ ۸ استفاده کنید.

پس از اتمام این کار ، باید یک خط به پرونده csproj پروژه خود اضافه کنید:

<Nullable>enable</Nullable>

توجه داشته باشید که در نسخه های قبلی SDK ممکن است به جای مورد فوق موارد زیر را لازم داشته باشد ، بنابراین موارد فوق را امتحان کنید و اگر آنچه انتظار دارید را نمی بینید، خط زیر را امتحان کنید!

<NullableReferenceTypes>true</NullableReferenceTypes>

Warnings To Expect

وقتی این ویژگی را روشن کردیم ، به یک کد ساده نگاه می کنیم تا آنچه را که اتفاق می افتد را نشان دهیم.

class MyClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }
}

static void Main(string[] args)
{
    MyClass myClass = null;
    myClass.SayHello();
}

با ساختن این ، دو اخطار دریافت می کنیم.

من آن را پررنگ قرار داده ام زیرا آنها هشدارها هستند و خطاها را کامپایل نمی کنند.

پروژه شما هنوز هم ساخته و اجرا خواهد شد ، اما این فقط به شما هشدار می دهد. هشدار اول برای ما خواهد بود.

Converting null literal or possible null value to non-nullable type.

و هشدار دوم وقتی است که می خواهیم از نوع nullableاستفاده کنیم و کامپایلر فکر می کند null خواهد بود.

Possible dereference of a null reference.

بنابراین هر دوی اینها متوقف نمی شوند که برنامه ما را اجرا کنند (yet, more on that later) ، اما به ما هشدار می دهد که ممکن است دچار مشکل شویم.

در عوض بگذاریم متغیر ما قابل تغییر نباشد.

من واقعاً کمی نگران بودم که syntaxمعکوس شود.

اکنون می توانید آن را در چیزی مانند NotNullable <MyClass> myClass…بگذارید.

اما خوشبختانه ، ما از همان syntax برای علامت گذاری یک نوع value، استفاده می کنیم:

static void Main(string[] args)
{
    MyClass? myClass = null;
    myClass.SayHello();
}

جالب اینجاست که اگر این مسئله را امتحان کنیم ، باز هم هشدار احتمالی دریافت می کنیم! بنابراین در حال حاضر فقط به این موضوع مربوط نمی شود ، شما در حال nullableهستید ، اما به طرز تبلیغاتی به ما هشدار می دهد ، شما در واقع بررسی نمی کنید که آیا این موضوع خنثی است یا خیر؟ برای خلاص شدن از شر آن ، باید null check خود بارگذاری کنیم.

static void Main(string[] args)
{
    MyClass? myClass = null;
    if (myClass != null)
    {
        myClass.SayHello();
    }
}

و درست مثل همین ، هشدارهای ما ناپدید می شوند.

محدودیت های هشدار کامپایلر

نکته این است که انواع مرجع را می توان بین روشها ، کلاسها ، حتی مجامع کل نیز به کار برد.

بنابراین هنگامی که هشدارها را خارج می کنید، مشکلی نیست. به عنوان مثال اگر کدی داریم که این گونه به نظر می رسد:

class MyClass
{
    public Random Random = new Random();
}


static void Main(string[] args)
{
    MyClass myClass = new MyClass();
    SomeMethod(myClass);
    var next = myClass.Random.Next(1, 10);
}

static void SomeMethod(MyClass myClass)
{
    myClass.Random = null;
}

ما اخطار می دهیم که در حال انتساب هستیم. اما ما اخطار Dereference ممکن را دریافت نمی کنیم.

این را می توانیم فرض کنیم که وقتی جسمی خارج از این روش منتقل شود ، هر اتفاقی که در آنجا رخ دهد (مانند تنظیم null ) ، ما نمی خواهیم درباره آن اخطار داده شود.

اما اگر ما در همان بلاک کد / روش صفر را قرار دهیم ، و سپس از آن استفاده کنیم ، کامپایلر سعی خواهد کرد که به ما کمک کند.

به خاطر مقایسه ، یک اخطار ایجاد میشود:

static void Main(string[] args)
{
    MyClass myClass = new MyClass();
    if (new Random().Next(1, 10) > 5)
    {
        myClass = null;
    }

    myClass.SayHello();
}

بنابراین فقط به این مسئله اطمینان نمی کنیم بلکه میخواهیم بدانیم در مورد کد فعلی هم امکان پذیر است یا خیر

Nullable Reference Types On Hard Mode

شما همیشه می توانید انواع مرجع nullable را بر روی حالت Hard قرار دهید و سعی کنید! به سادگی موارد زیر را به csproj پروژه خود اضافه کنید:

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

توجه داشته باشید که این با تمام هشدارها * به عنوان خطا رفتار می کند ، نه فقط موارد مربوط به موارد مرجع پوچ.

اما این بدان معناست که اگر هشدارهایی در مورد پرتاب وجود داشته باشد ، پروژه شما دیگر کامپایل نخواهد شد!

Final Note

فکر می کنم فقط بیان چند نکته دیگر در این مورد کافی است.

  • این موضوع مرا به یاد بسیاری از کلمات کلیدی In که در C # 7.2 معرفی شده است ، می اندازد. این چند مزیت عملکردی داشت ، اما در واقع اصل این بود که (intent ) “نیت” برنامه نویس را نشان دهیم. ما در اینجا یک چیز مشابه داریم
  • حتی اگر از ویژگی آن کاملاً مطمئن نیستید ، تقریباً ارزش آن را دارد که بررسی اش کنید که هشدارهای مربوط به تغییر مکان برای یک پروژه موجود چگونه است. این یک خط تغییر است که به راحتی می توان آن را روشن و خاموش کرد.
  •  من این واقعیت را دوست دارم که هشدارها وجود داشته باشند و خطا نباشند. این کار باعث می شود تا یک پروژه منتقل شود و به راحتی بتوان از آن استفاده کند ، اگر با هشدارهایی که در طول یک ماه نشان داده می شود خوب هستید پس این مطلب را به درستی درک کرده اید!
  • هنگام شروع یک پروژه جدید در سی شارپ ، به طور پیش فرض در هنگام شروع کار جدید ، این ویژگی وجود دارد. این نسخه هنوز تکمیل نشده است، اما می تواند در آینده اتفاق بیفتد. بنابراین ارزش این را دارد که درک کنیم چطور کارها خوب پیش میرود زیرا شما ممکن است در آینده به پروژه ای بر بخورید که بخواهید از آن استفاده کنید.
  • پسورد: www.mspsoft.com
زهره سلطانیان

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

کدیشن ! مارکت پروژه های برنامه نویسی راه اندازی شدیه توکه پا بریم ببینم