קובץ ProductRepsitory.cs
public async Task<Product?> GetProductById(int id) {
await Task.Delay(500);
var item = this._products.FirstOrDefault(x => x.id == id);
if(item == null) {
return null;
}
return item;
}
בפונקציה שלמעלה עשינו שימוש ב-Product עם ?. נראה מה המשמעות של זה.
סוגי אחסון נתונים
בגרסאות ישנות של .Net היה לנו הבדל בין משתנים by value ולמשתנים by reference. משתנים by value הם כל הפרימיטיבים, כמו int, bool וכו'. הערך שמור בתוך המשתנה שיש לנו בזיכרון.
אם יש לנו אובייקטים שאנחנו מייצרים, מדובר על reference. זה אומר שבמקום בזיכרון שאליו אנחנו פונים נמצאת הכתובת שבו נמצא האובייקט עצמו. כאשר אנחנו פונים לכתובת שלא מוגדר בה אובייקט, אנחנו מקבלים null.
אם יש לנו קוד כזה:
Person p = null;
Console.WriteLine(p.name);
class Person
{
public string name { get; set; )
}
הוד תקין מבחינת כתיבה, אבל כשנריץ אותו נקבל שגיאה, מכיוון שאנחנו מנסים לגשת למשתנה של אובייקט שלא קיים.
אם ננסה להגדיר משנה פרימיטיבי = null זה לא יעבור קומפילציה, כי משתנה value לא יכול להכיל null.
יש לנו בעיה גם עם databases ששם יכול להיות לי שדה מסוג int שישב בו null. לא תמיד יהיה לי נכון לשים שם 0 ולא null.
מכיוון שזה יצר בעיה, נוצר לנו nullable, כלומר להגיד שהמשתנה הזה יכול להיות null. א זה עושים על ידי הוספת ה-?
// לא יעבור קומפילציה
int p = null;
// יעבור קומפילציה
int? p = null;
מה שקורא בפועל זה שההוספה של ה-? הופכת את המשתנה שהוא by value למשתנה אחר שהוא by reference ובצורה הזאת אפשר לשים null גם במשתנים שלא אמורים לקבל את זה.
עכשיו יכולה להיות בעיה נוספת, נניח שיש לי ב-DB שדה שהוא string ולא יכול לקבל null. מה קורה כשאנחנו מגדירים אותו ב-net? הוא יכול לקבל null לפי ההגדרה שלו. לכן microsoft עושה שינוי שבו גם string של יכול להיות null אם לא נאפשר לו א זה, וכרגע זה ברמה של לתת אזהרה. ולכן גם ל-string אם נראה שהוא יקבל null, נצטרך להוסיף לו ? וכך לגבי המשתנים שהם by reference.
פונקציה שמחזירה null
נניח שיש לנו מערך שאני משתמשת ב-FirstOrDefault לקבל ממנו ערך מסויים ושמה אותו במשתנה result. יתכן שלא יהיה ערך שיתאים לתנאי שלי ואני אקבל null. אם אני אנסה לגשת לאיזה property של result כשהוא null אני אקבל שגיאה.
ולכן, אם אני בטוחה שאני אקבל ערך מהתנאי הזה, עדיף להשתמש ב-First ולא ב-FirstOrDefault. ואז אם אין לי תוצאה אני אקבל את השגיאה מתוך הפונקציה שבודקת.
שימוש ב-!
יש אפשרות להשתמש ב-! על מנת להסיר את ההערה ממשתנה כשיש אזהרת null. השימוש ב-! אומר שבטוח יש לי ערך במשתנה. זו טעות להשתמש בזה כי בעולם הפיתוח כי בדרך כלל אין לנו אפשרות להבטיח את זה וזה מייצר שגיאות. רק אם יש בדיקות שמוודאות שזה לא null וה-compiler לא מצליח להבין את זה, נשתמש ב-!
אם נבדוק שהמשתנה != null לפני הפנייה לפונקציה, ה-compiler יראה שביצענו בדיקה ולא יראה שגיאה.