Generic
פונקציות ג'נריות מאפשרות לנו לכתוב פעם אחת קוד שמתאים למספר סוגים של משתנים.הקוד מקבל כפרמטר את סוג המשתנים ומגיב בהתאם.
דוגמא - פונקציה ג'נרית להדפסת מערך פשוטה:
(אפשר לתת לסוג המשתנים כל שם, כאן נשתמש ב-"E".)
class Program { // פונקציה ג'נרית להדפסה של איברי מערך מכל סוג מספרי static void PrintArray<E>(E[] inputArray) { foreach (E element in inputArray) Console.Write(element + ", "); Console.WriteLine("\n"); } static void Main(string[] args) { // double ו int יצירת מערך של int[] intArray = { 1, 2, 3, 4, 5, 6 }; double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; // int הדפסת מערך PrintArray<int>(intArray); // 1, 2, 3, 4, 5, 6, :ידפיס // double הדפסת מערך PrintArray<double>(doubleArray); // 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, :ידפיס } }
דוגמא - מחלקה ג'נרית לייצוג נקודה:
(אפשר לתת לסוג המשתנים כל שם, כאן נשתמש ב-"T".)
// מחלקה ג'נרית שמייצגת נקודה class Point<T> { private T x; private T y; public Point(T x, T y) { this.x = x; this.y = y; } public void show() { Console.WriteLine("x: {0} y: {1}", x, y); } } class Program { static void Main(string[] args) { // נקודה של פרמטרים מספריים שלמים Point<int> IntP = new Point<int>(10, 5); // נקודה של פרמטרים מספריים עשרוניים Point<double> DoubleP = new Point<double>(10.5, 5.7); // נקודה של פרמטרים מסוג מחרוזת Point<string> StringP = new Point<string>("a7", "b3"); // הדפסה IntP.show(); // x: 10 y: 5 :ידפיס DoubleP.show(); // x: 10.5 y: 5.7 :ידפיס StringP.show(); // x: a7 y: b3 :ידפיס } }
דוגמא - מחלקה ג'נרית לייצוג נקודה עם שני סוגים שונים של צירים:
(אפשר לתת לסוג המשתנים כל שם, כאן נשתמש ב-"T1" ו-"T2".)
// מחלקה ג'נרית שמייצגת נקודה עם שני סוגים שונים של צירים class Point<T1, T2> { private T1 x; private T2 y; public Point(T1 x, T2 y) { this.x = x; this.y = y; } public void show() { Console.WriteLine("x: {0} y: {1}", x, y); } } class Program { static void Main(string[] args) { // נקודה של פרמטרים מספריים שלמים Point<int, int> IntIntP = new Point<int, int>(10, 5); // נקודה של פרמטר שלם ופרמטר עשרוני Point<int, double> IntDoubleP = new Point<int, double>(10, 5.7); // הדפסה IntIntP.show(); // x: 10 y: 5 :ידפיס IntDoubleP.show(); // x: 10 y: 5.7 :ידפיס } }
דוגמא - מחלקה ג'נרית לייצוג אדם עם "איזור מידע אישי" שיצרנו בעצמנו:
namespace ConsoleApplication72 { // ייצוג מבחר פרטים אישיים class PersonInformation { public int Age; public String Phone; public String Country; public PersonInformation(int Age, String Phone, String Country) { this.Age = Age; this.Phone = Phone; this.Country = Country; } public override string ToString() { return "Age: " + Age + " Phone: " + Phone + " Country: " + Country; } } // מחלקה שמייצגת אדם עם קובץ מידע שניתן לשנות class Person<T> { private int ID; private String FirstName; private String LastName; private T PersonalInformation; public Person(int ID, String FirstName, String LastName, T PersonalInformation) { this.ID = ID; this.FirstName = FirstName; this.LastName = LastName; this.PersonalInformation = PersonalInformation; } // ( מאפשר ליצור פונקציה בעלת שם שכבר קיים במחלקה שירשנו override ) public override string ToString() { return "Name: " + FirstName + " " + LastName + ". ID: " + ID + "\nInformation:\n" + PersonalInformation + "."; //// String בעת ניסיון המרה משתמע ל toString מופעלת אוטומטית הפונקציה C# ב //// :באותה מידה היינו יכולים לכתוב //// return ID.ToString() + FirstName + LastName + PersonalInformation.ToString(); } } class Program { static void Main(string[] args) { // יצירת קטע מידע על האדם PersonInformation info = new PersonInformation(25, "0503365542", "Israel"); // יצירת אדם בשילוב קטע המידע שיצרנו Person<PersonInformation> person1 = new Person<PersonInformation>(264738799, "Noam", "Nol", info); // ToString() הפונקציה תמיד תפעיל אוטומטית את Console.WriteLine(person1); // :ידפיס //Name: Noam Nol. ID: 264738799 //Information: //Age: 25 Phone: 0503365542 Country: Israel. } } }
דוגמא - מחלקה לייצוג מעגל שיורשת באופן לא ג'נרי מהמחלקה הג'נרית "Point":
(ניתן להזין לנקודות הציון ולקוטר רק ערכים מסוג double)
// מחלקה ג'נרית שמייצגת נקודה class Point<T> { private T x; private T y; public Point(T x, T y) { this.x = x; this.y = y; } public T GetX() { return x; } public void SetX(T x) { this.x = x; } public T GetY() { return y; } public void SetY(T y) { this.y = y; } public override string ToString() { return "x: " + x + ", y: " + y; } } // שני מאפיינים יש למעגל בשטח דו ממדי: קוטר ונקודה // בלבד double כאן אנחנו יורשים את המחלקה "נקודה" בתצורה של class Circle : Point<double> { // קוטר מעגל private double Diameter; // פונקציה בונה public Circle(double x, double y, double Diameter) : base(x, y) { // משמש לגישה לשדות ופונקציות (ציבוריים) של המחלקה שירשנו ממנה base // (override) שימושי לפונקציות בעלות שם זהה // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/base this.Diameter = Diameter; } public double GetDiameter() { return Diameter; } public void SetDiameter(double Diameter) { this.Diameter = Diameter; } public override string ToString() { return base.ToString() + ", Diameter: " + Diameter; } } class Program { static void Main(string[] args) { Circle circ = new Circle(20.4, 30.5, 100); Console.WriteLine(circ); // x: 20.4, y: 30.5, Diameter: 100 :ידפיס } }
דוגמא - מחלקה ג'נרית לייצוג מעגל שיורשת באופן ג'נרי מהמחלקה הג'נרית "Point":
// מחלקה ג'נרית שמייצגת נקודה class Point<T> { private T x; private T y; public Point(T x, T y) { this.x = x; this.y = y; } public T GetX() { return x; } public void SetX(T x) { this.x = x; } public T GetY() { return y; } public void SetY(T y) { this.y = y; } public override string ToString() { return "x: " + x + ", y: " + y; } } // שני מאפיינים יש למעגל בשטח דו ממדי: קוטר ונקודה // כאן אנחנו יורשים את המחלקה "נקודה" בתצורה ג'נרית class Circle<T> : Point<T> { // קוטר מעגל private T Diameter; // פונקציה בונה public Circle(T x, T y, T Diameter) : base(x, y) // Point שליחה לפונקציה בונה של המחלקה { // משמש לגישה לשדות ופונקציות (ציבוריים) של המחלקה שירשנו ממנה base // (override) שימושי לפונקציות בעלות שם זהה // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/base // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords this.Diameter = Diameter; } public T GetDiameter() { return Diameter; } public void SetDiameter(T Diameter) { this.Diameter = Diameter; } public override string ToString() { return base.ToString() + ", Diameter: " + Diameter; } } class Program { static void Main(string[] args) { Circle<int> circ = new Circle<int>(20, 30, 100); Console.WriteLine(circ); // x: 20, y: 30, Diameter: 100 :ידפיס } }
תכנות ג'נרי עושה שימוש רב ב interface, נושא עליו נלמד בהמשך.
ראו גם: מדריך #C מתקדם - Generics: Constraints – התניות על פרמטרים גנריים
אין תגובות:
הוסף רשומת תגובה