שימוש במחלקות בסיס וממשקים
אל:
1 | public class Serializer |
עדיף:
1 | public interface ISerializer |
ניתן ליצור מופעים ממחלקות ולכן אם המחלקה לא אבסרקטית או בנויה כממשק אז למופע שלה לא יהיה ערך אמיתי,
העדיפו פונקציות גנריות על פני object
אל:
1 | public interface ISerializer |
עדיף:
1 | public interface ISerializer |
הסיבה לכך היא השימוש ב-boxing
.
כאשר int
נאסף ע”י ה-CLR הוא צריך להיות מיוצג כמחלקה כדי לתאר אותו כאובייקט.
בגלל ההבדל בין Value type
ל-Reference Type
.
כאשר משתמשים בקוד גנרי נוצרים פונקציות ספציפיות עבור סוגי המשתנים.
השתמשו ב-Record במקום Class
אל:
1 | public class Person |
עדיף:
1 | public record Person(string Name); |
או:
1 | public record Person |
ב-C# 9.0 הוסיפו record
אשר עוזר לממש מחלקות מודלים בקלות.
העדיפו IEnumerable על פני רשימות קונקרטיות
אל:
1 | public class Namer |
עדיף:
1 | public class Namer |
השימוש ברשימות מכריח את הקוד להשתמש במחלקה קונקרטית של רשימה ובכך מכריח שימוש באלגוריתם ספציפי.
אם נרצה לבנות את הקוד שלנו להשתמש בסוג אחר:
רשימה מקושרת, מערך, רשימה מסודרת או משהו אחר - לא נוכל להשתמש בזה מבלי לאבד את השימוש באלגוריתם.
כמו כן זה מכריח את המשתמש ליצור מופעים חדשים ואף להעתיק את הערכים, במידה ומס’ הערכים עצום זה ייעלה לנו בזיכרון וביצועים.
העדיפו שימוש ב-Readonly
אל:
1 | public class ServiceClass |
עדיף:
1 | public class ServiceClass |
במידה ומשתנה במחלקה יהיה מאותחל פעם אחת בלבד - נרצה להימנע מתאחול מחדש של המשתנה.
השתמשו בפורמט במקום פונקציות חיבור מחרוזות, או StringBuilder
אל:
1 | string a = "Hello"; |
עדיף:
1 | string a = "Hello"; |
או
1 | StringBuilder builder = new StringBuilder(); |
הימנעו מ-is או as
אל:
1 | object MyObj = fromObject; |
עדיף:
1 | object MyObj = fromObject; |
השימוש החדש בswitch
עם pattern matching
הוא כלי חזק ויעיל לבניית בדיקות.
בכללי אני מעדיף לא להשתמש בבדיקת Type
אלה להשתמש בהם בעזרת תבנית האסטרגיה.
אבל במידה ואתם ממש צריכים את זה, ניתן להשתמש בזה באופן הזה :)
תשדרגו את ה-Attributeים שלכם לגנריים !
אל:
1 | [ ] |
עדיף:
1 | [ ] |
C# 11.0 הוסיפו פיצ’ר לאפשר Attribute
גנרי!
כדאי להשתמש בזה כי שימוש ב-typeof
איטי יותר.
השתמשו ב-ref struct כדי להימנע משימוש ב-Heap
אל:
1 | struct Data |
עדיף:
1 | ref struct Data |
קיימים לפיצ’ר מגבלות רבות אך אם אתם רוצים להימנע מהמשתנה שלכם לעבור boxing
ולגרוע מביצועים - זו הדרך לבצע את זה.
העדיפו ValueTask על Task בקוד הדורש ביצועים
אל:
1 | public Task<byte[]> Read(Stream s); |
עדיף:
1 | public ValueTask<byte[]> Read(Stream s); |
במקרים שלא צריך לבצע קריאה ל-Task
כמו כאשר התוצאה קיימת לנו כבר, אז נוכל לגרוע את האלוקציה ל-Task
.
במידה ואתם משתמשים ב-ValueTask<T>
נחסוך את ההקצאה בכך לא נגרע מהביצועים!