Browse by Tags
All Tags »
C# »
Coding Practices (
RSS)
אם יש משהו אחד בסיסי שכולם יודעים על פיתוח תוכנה, הוא שלא ניתן ליצור תלות מעגלית בין פרוייקטים (DLL'ים). אם למשל יש לנו פרוייקט A, שפונה לפרוייקט B, אז לא יהיה ניתן שאותו פרוייקט B יפנה בחזרה לפרוייקט A בתור רפרנס. אם היינו עושים דבר כזה, היתה נוצרת לנו תלות מעגלית בין שני הפרוייקטים. וזה רע, בגלל שכשהקומפיילר ירצה לקמפל את A, הוא יראה שהוא תלוי ב-B, אז הוא יגש ל-B וינסה לקמפל אותו. אבל אז הוא יגלה ש-B למעשה תלוי ב-A, ואז הוא יחזור חלילה עד אין קץ.. האמנם? אם יצא לכם לפשפש מספיק במבנה הספריות...
אם יש דבר אחד שאני לא אוהב לראות בקוד, זה שימוש מוגזם ב- Region 'ים. הטיעון העיקרי של התומכים בשימוש באותם Region'ים הוא שאפשר להגיע בעזרתם לקוד הרבה יותר "נקי", "מסודר", או חס וחלילה, "קל לתחזוקה". תלוי ביום, ומצב הרוח שלי באותו רגע, אני אוטומטית משיב: הפוך גוטה, הפוך . הדבר היחיד ש-Region'ים יודעים לעשות זה להחביא קוד . מה שלעצמו מרגיש די אבסורדי מאחר ורובנו בדרך כלל נמצאים במירוץ לא נגמר אחרי מסך גדול יותר, רזולוציה מטורפת יותר, פונט קטן יותר - העיקר להכניס...
שימוש ב-Assert יכול להיות פתרון נוח ושימושי כשרוצים לוודא שה-State שאנחנו נמצאים בו כרגע, באמת מתאים למה שאנחנו מצפים. אנחנו יכוללים להשתמש בו בשביל לבדוק כל מיני מקרי קצה ביזארים, כל מיני מצבים ש"אין מצב" שיקרו (על פי הלוגיקה הקיימת בקוד). כל מיני מצבים שהמשך הקוד שלנו מסתמך על זה שהם לא אפשריים, ולא יקרו בזמן הוא רץ. בדרך כלל נקרא ל-Assert דרך המחלקה הסטאטית Debug, שעושה שימוש ב- ConditionalAttribute עם הערך "DEBUG", כך שאנחנו יודעים שכל הבדיקות האלו לא יעלו לנו כלום כשנצא לגרסת...
דבר אחד שימושי בדוט-נט הוא התמיכה הטבעית הקיימת ל-Event'ים. כדי ליצור אירוע למחלקה שלנו, כל מה שעלינו לעשות הוא להגדיר Event חדש בעזרת ה-Delegate המתאים, וזהו זה. שימו לב שאפילו לא היינו צריכים לכתוב Accessors כלשהם, מאחר וכברירת מחדל, אלא אם כן לא הגדרנו אחרת, הקומפיילר יחולל כבר Accessor'ים משלו שידאגו לנהל עבורנו את הרישומים עבור האירוע שהגדרנו. זוהי נקודה שהרבה פעמים לוקחים כמובן מאליו, ולא מפנים אליה תשומת לב מיוחדת, ולמרות זאת, מסתתרת מאחוריה משמעות קריטית כש-Multithreading נכנס לתמונה...
לפני כמה פוסטים הבנו מה המשמעות של אופרטור ההשוואה (==) כשנעשה בו שימוש בקונטקסט של Reference Types. למעשה הגענו למסקנה שבמימוש הבסיס הוא למעשה עונה לנו על השאלה "האם 2 הרפרנסים שיש לי מצביעים לאותו אובייקט?", כלומר יש לנו כאן השוואה של כתובות בזכרון. אם הן זהות, קיבלנו true; אחרת, false. אבל רק רגע, בנקודה הזאת אנחנו נזכרים לרגע בפונקציה ReferenceEquals שנמצאת תחת מחלקת הבסיס Object. כמו שמשתמע מהשם, גם התפקיד שלה הוא לענות בדיוק על אותה השאלה. אז אם 2 הדרכים הללו למעשה "עושות אותו...
רובנו כבר יודעים לשנן את האימרה שאומרת שכשאנחנו כותבים קוד, אנו כותבים אותו עבור בני אדם, ולאו דווקא למחשב, ולכן יותר חשוב שהקוד שאנו כותבים יהיה יותר קריא מיעיל. למרות זאת, פעמים רבות אנו שוכחים פרטים קטנים שלאו דווקא פוגעים בקריאות הקוד, כאלו שלא נראים לנו חשובים בעת כתיבת הקוד. למעשה, אני מדבר על כתיבת קוד שיהיה נוח לדבג. כי אם החוק אומר שנשקיע יותר זמן בקריאת קוד מאשר בכתיבת קוד, אז הכרחי שהזמן שנעביר בלדבג את הקוד יעלה כנראה על הזמן שנדרש לכתוב או לקרוא את הקוד גם יחדיו. לכן, כדי לעשות את ה"אקסטרה"...
ב-#C יש 2 דרכים לביצוע cast בין טיפוסים. הראשונה היא הדרך הסטנדרטית והמוכרת: class Person { } class Program { static void Main() { object foo = new Person (); Person bar = ( Person )foo; } } ולעומתה, השימוש במילת המפתח "as": object foo = new Person (); Person bar = foo as Person ; ההבדלים ניסיון לבצע קאסט "סטנדרטי" על טיפוסים שאין ביניהם קשר של הורשה/מימוש (למשל ניסיון לבצע קאסט בין מחלקת Car לבין Apple), יוביל לזריקת שגיאה מסוג InvalidCastException. לעומת זאת, ניסיון לבצע קאסט...