در سی شارپ دو نوع تایپ وجود دارد. ValueType و ReferenceType. این تایپ‌ها ویژگی‌های مختص به خود را دارند. یکی از آن ویژگی‌هایی که در این مطلب میخواهیم درباره آن صحبت کنیم قرار دادن مقدار Null در ValueTypeها می‌باشد. ReferenceTypeها دیتای اصلی را درون خود ذخیره نمی‌کنند، بلکه آدرس مربوط به دیتارا ذخیره می‎‌کنند. در واقع ReferenceTypeها مانند یک Pointer عمل می‌کنند که آدرس محلی که دیتای اصلی در آن ذخیره شده است را نگه‌ می‌دارند و زمانی که مقدار Null را به یک ReferenceType اختصاص می‌دهیم، مقدار آدرس برابر Null می‌شود و یعنی به جایی اشاره نمی‌کند. اما ValueTypeها به این صورت عمل نمی‌کنند و آنها دیتای اصلی را درون خود ذخیره می‌کنند نه آدرس دیتای اصلی را، به همین دلیل نمیتوانیم  مقدار Null را درون یک ValueType ذخیره نماییم. اما برای حل این مشکل در سی شارپ 2 یک struct به نام Nullable ایجاد شد که این قابلیت را به ما می‌دهد که بتوانیم برای ValueTypeها نیز مقدار Null را در نظر بگیریم(با کمی تفاوت). 

Nullable<int> number = null;

استراکت Nullable به صورت جنریک نوشته شده است که تایپ ورودی آن باید حتما ValueType باشد. به طور مثال شما نمی‌توانید یک رفرنس تایپ را به ورودی Nullable ارسال کنید

Nullable<Type> type = typeof(Type);//Compilation error!

Nullable شامل دو پراپرتی Value و HasValue می‌باشد و فقط زمانی پراپرتی Value آن مقداردهی می‎‌شود که در مرحله اول توسط سازنده آن مقداردهی شده باشد و در صورتی که مقدار ذخیره شده برابر Null باشد و پراپرتی Value را فراخوانی کنیم، با خطای Null reference مواجه می‌شویم.

public bool HasValue 
{
    [System.Runtime.Versioning.NonVersionable]
    get
    {
         return hasValue;
    }
} 

public T Value 
{
    get 
    {
         if (!hasValue) 
         {
              ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
         }
          return value;
     }
}

ما می‌توانیم مقدار Null را در یک متغییر Nullable int ذخیره کنیم. اما در پشت صحنه عملا کار دیگری انجام می‌شود. در واقع کد زیر:

Nullable<int> number = null;

به این کد تبدیل می‌شود:

Nullable<int> number = new Nullable<int>();

در واقع این کار از سمت توسعه دهنده پنهان می‎یاشد و خود کامپایلر این کار را انجام می‎دهد. دلیل این کار آن است که ما نمی‌توانیم مقدار null را درون یک ValueType ذخیره کنیم. بنابراین زمانی که ما یک متغییر Nullable از نوع int تعریف می‌کنیم، مقدار پیشفرض آن تایپ (برای تایپ int مقدار 0) در مموری قرار می‌گیرد و عملا مقدار Null برای ValueType ها در مموری ذخیره نمی‌شود. 

Nullable در سی شارپ یک struct است که شامل استثناهایی می‌باشد که توسعه دهنده نمی‌تواند آنها را پیاده سازی کند. برای مثال اگر شما تمامی کدهای مربوط به Nullable را دریافت کنید و یک struct جدید به نام CustomNullable تعریف کنید، نمی‌توانید مقدار Null را درون آن ذخیره کنید زیرا struct مربوط به Nullable درون سی شارپ به عنوان یک struct ویژه شناسایی شده است که می‌تواند کارهایی متفاوتی انجام دهد.

منابع استفاده شده برای این مطلب:

Powered by Froala Editor

نظرات