Menu
Coddy logo textTech

Generics (מחלקות ומתודות)

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 42 מתוך 70.

טיפוסים גנריים מאפשרים לך לכתוב מחלקות ומתודות שעובדות עם כל סוג נתונים תוך שמירה על בטיחות הטיפוסים. במקום לכתוב מחלקות נפרדות עבור IntList, StringList ו־DoubleList, כותבים מחלקה גנרית אחת שמטפלת בכולן.

מחלקה גנרית משתמשת בפרמטר טיפוס, שבדרך כלל נקרא T, והוא מוקף בסוגריים זוויתיים:

public class Box<T>
{
    private T content;
    
    public void Store(T item) => content = item;
    public T Retrieve() => content;
}

// שימוש עם סוגים שונים
Box<int> intBox = new Box<int>();
intBox.Store(42);

Box<string> stringBox = new Box<string>();
stringBox.Store("Hello");

כשיוצרים Box<int>, המהדר מחליף כל T ב-int. כך מתבצעת בדיקת טיפוסים בזמן הידור — אי אפשר לאחסן בטעות מחרוזת בתיבה מסוג int.

מתודות גנריות פועלות באופן דומה ומאפשרות למתודה יחידה לפעול עם סוגים שונים:

public static void Swap<T>(ref T a, ref T b)
{
    T temp = a;
    a = b;
    b = temp;
}

int x = 1, y = 2;
Swap(ref x, ref y);  // x=2, y=1

המהדר מסיק את הטיפוס מהארגומנטים, כך שאין צורך לכתוב במפורש Swap<int>. גנריות הן הבסיס לאוספים כמו List<T> ו־Dictionary<TKey, TValue>, ומאפשרות כתיבת קוד לשימוש חוזר ובטוח מבחינת טיפוסים.

challenge icon

אתגר

קל

בואו נבנה מערכת גנרית של Storage<T> שיכולה להכיל פריטים מכל סוג ולנהל אותם. תיצרו מחלקת מכל לשימוש חוזר שמדגימה את העוצמה של גנריות — כותבים פעם אחת ומשתמשים עם מספרים שלמים, מחרוזות או כל סוג אחר!

תארגנו את הקוד שלכם בשני קבצים:

  • Storage.cs: צרו מחלקה גנרית Storage<T> במרחב השמות DataStorage. מכל האחסון שלכם צריך:
    • להכיל מערך פרטי מסוג T לאחסון הפריטים, ומאפיין Count שעוקב אחר מספר הפריטים המאוחסנים
    • לקבל קיבולת בבנאי כדי לאתחל את המערך הפנימי
    • להכיל מתודת Add(T item) שמוסיפה פריט אם יש מקום
    • להכיל מתודת Get(int index) שמחזירה את הפריט באינדקס שצוין
    • להכיל מתודת GetAll() שמחזירה את כל הפריטים המאוחסנים כשהם מחוברים באמצעות ", "
  • Program.cs: בקובץ הראשי שלכם, הדגימו את המחלקה הגנרית שלכם עובדת עם שני סוגים שונים. צרו Storage<int> ו-Storage<string>, הוסיפו פריטים לכל אחד מהם והראו שאותה מחלקה פועלת בצורה חלקה עם שני הסוגים.

תקבלו ארבעה קלטים:

  • המספר השלם הראשון לאחסון
  • המספר השלם השני לאחסון
  • המחרוזת הראשונה לאחסון
  • המחרוזת השנייה לאחסון

צרו אחסון למספרים שלמים בקיבולת 5 ואחסון למחרוזות בקיבולת 5. הוסיפו את שני המספרים השלמים לאחסון המספרים השלמים ואת שתי המחרוזות לאחסון המחרוזות.

הדפיסו את הפלט בפורמט הזה:

Int storage: {GetAll()}
Int count: {Count}
First int: {Get(0)}
String storage: {GetAll()}
String count: {Count}
First string: {Get(0)}

לדוגמה, אם הקלטים הם 42, 100, Hello ו-World, הפלט צריך להיות:

Int storage: 42, 100
Int count: 2
First int: 42
String storage: Hello, World
String count: 2
First string: Hello

שימו לב שאתם כותבים את המחלקה Storage<T> פעם אחת, אבל היא פועלת בצורה מושלמת גם עם int וגם עם string — זה הקסם של גנריות! המהדר מבטיח בטיחות טיפוסים, כך שלא תוכלו להוסיף בטעות מחרוזת לאחסון המספרים השלמים שלכם.

נסו בעצמכם

using System;
using DataStorage;

class Program
{
    public static void Main(string[] args)
    {
        // קראו את הקלטים
        int num1 = Convert.ToInt32(Console.ReadLine());
        int num2 = Convert.ToInt32(Console.ReadLine());
        string str1 = Console.ReadLine();
        string str2 = Console.ReadLine();

        // TODO: צרו Storage<int> עם קיבולת של 5
        
        // TODO: הוסיפו את שני המספרים השלמים לאחסון המספרים השלמים
        
        // TODO: צרו Storage<string> עם קיבולת של 5
        
        // TODO: הוסיפו את שתי המחרוזות לאחסון המחרוזות
        
        // TODO: הדפיסו את הפלט בפורמט הנדרש
        // Int storage: {GetAll()}
        // מספר המספרים השלמים: {Count}
        // המספר השלם הראשון: {Get(0)}
        // String storage: {GetAll()}
        // String count: {Count}
        // First string: {Get(0)}
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C# אונליין