سلام خدمت همراهان مقالات آموزش ASP.NET سایت میزفا ؛
در این جلسه آموزشی با عملگر شرطی Null در سی شارپ آشنا خواهیم شدیم که یک عملگر بسیار مفید برای جلوگیری از خطاهای احتمالی برنامه شماست. برای شروع کار پروژه ای که در جلسه گذشته کامل نموده ایم را باز کنید.
کاربرد عملگر شرطی Null در #C
با استفاده از عملگر شرطی Null به فرم هوشمندانه تری میتوانید با مقدارهای تهی برخورد کنید . در برنامه نویسی MVC به موارد زیادی برخورد میکنید که در آنها نیاز به آزمایش تهی بودن مقدارهای دریافتی دارید . در روش مرسوم ، آزمایش تهی بودن اشیاء ، به ویژه جایی که باید یک شی و خصوصیت های آن را برای تهی بودن آزمایش کنید، باید به صورت صریح انجام گیرد.این کار به طور معمول وقت گیر است و از سویی نمیتواند خالی از اشتباه هم باشد. عملگر یاد شده ، اینکار را به شکل سادهتر و دقیقتری انجام میدهد.
پروژه ای که در جلسه گذشته ایجاد نموده اید را باز کنید سپس در کنترلر Home اکشن متد Index را به صورت زیر ویرایش کنید دقت کنید که شما باید فضای نام ;using ProjectName.Models را به کنترلر Home اضافه کنید فقط به جای ProjectName نام پروژه خود را قرار دهید. درصورت اضافه نکردن این namespace یا فضای نام ، پروژه شما با خطا مواجه میشود.
using LearnCSharp.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LearnCSharp.Controllers { public class HomeController : Controller { public ViewResult Index() { List<string> results = new List<string>(); foreach (Product p in Product.GetProducts()) { string name = p?.Name; decimal? price = p?.Price; results.Add(string.Format("Name:{0},Price:{1}", name, price)); } return View(results); } } }
متد استاتیک ()GetProducts در کلاس Product آرایه ای از اشیا را بازمیگرداند که در متد اکشن برای دریافت لیستی از محصولات و قیمت های آنها ، فراخوانی میشود مشکل اینجاست که هم خود شیء موجود در آرایه و هم مقدار خصوصیت آن ممکن است Null باشد بنابراین اشاره به p.Price در حلقهی foreach میتواند با خطای NullReferenceException برخورد کند. برای پرهیز از این خطا از عملگرشرطی یاد شده به صورت زیر استفاده می کنیم.
... string name = p?.Name; decimal? price = p?.Price; ...
این عملگر همانطور که میبینید نماد ? است اگر P تهی باشد متغیر name هم تهی میشود . همین کار در مورد خصوصیت Price هم انجام می شود. توجه کنید که هنگام کاربرد این عملگر ، متغیر دریافت کننده مقدار ، قابلیت پذیرش تهی را داشته باشد. در مثال بالا نوع متغیر name ، رشته یا string است و همانطور که می دانید string می تواند مقدار تهی یا Null را هم بپذیرد اما نوع متغیر decimal ، price است و decimal مقدار Null را نمی پذیرد به همین دلیل بعد از decimal از عملگر ? استفاده کرده ایم تا تهی پذیر شود.
عملگرهای شرطی Null می تواند برای آزمایش سلسه مراتبی از اشیاء ، پشت سرهم آورده شود و بدین صورت کد ایجاد شده را بسیار ساده کنند . در کد زیر خصوصیت جدیدی با نوع Product به کلاس Product اضافه کرده ایم .
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LearnCSharp.Models { public class Product { public string Name { get; set; } public decimal? Price { get; set;} public Product Related { get; set;} public static Product[] GetProducts() { Product Kayak = new Product { Name="Kayak" , Price =275M }; Product lifejacket = new Product { Name = "Lifejacket", Price = 48.95M }; Kayak.Related = lifejacket; return new Product[] { Kayak, lifejacket, null }; } } }
هر شی Product دارای خاصیتی به نام Related است. که میتواند به شی Product دیگری اشاره کند این خاصیت را برای شیئی از Product به نام kayak مقداردهی کرده ایم . کد زیر نشان میدهد که چگونه میتوانیم با استفاده از عملگر شرطی Null در بین خاصیت های شیئی از Product حرکت کنیم.
using LearnCSharp.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LearnCSharp.Controllers { public class HomeController : Controller { public ViewResult Index() { List<string> results = new List<string>(); foreach (Product p in Product.GetProducts()) { string name = p?.Name; decimal? price = p?.Price; string relateName = p?.Related?.Name; results.Add(string.Format("Name:{0},Price:{1},Related:{2}", name, price,relateName)); } return View(results); } } }
نتیجه این است که تهی بودن هر دوی P و P.Related موجب تهی شدن متغیر relatedName خواهد شد. اگر این مقدارها تهی نباشند ، مقدار را به خود خواهد گرفت. اجرای این برنامه ، نتیجه زیر را در پنجره مرورگر نشان خواهد داد.
ترکیب عملگر ? با عملگر ?? برای نمایش بهتر مقادیر تهی در خروجی برنامه ، مفید خواهد بود. کد اکشن متد Index را به صورت زیر ویرایش کنید.
using LearnCSharp.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LearnCSharp.Controllers { public class HomeController : Controller { public ViewResult Index() { List<string> results = new List<string>(); foreach (Product p in Product.GetProducts()) { string name = p?.Name??"<No Name>"; decimal? price = p?.Price??0; string relateName = p?.Related?.Name??"<None>"; results.Add(string.Format("Name:{0},Price:{1},Related:{2}", name, price,relateName)); } return View(results); } } }
با کاربرد عملگر ? میتوان مطمئن بود که خطای NullReferenceException رخ نخواهد داد و استفاده از ?? موجب میشود که مقدارهای تهی در خروجی برنامه ، نمایش داده نشوند.
خروجی برنامه به صورت زیر خواهد بود.
به پایان این جلسه از آموزش ASP.NET Core رسیدیم درصورتی سوالی داشتید حتما در قسمت نظرات این مقاله آموزشی مطرح کنید.