31. More generic constraints

בוקר טוב,

אמרנו באחד הטיפים הקודמים שאי אפשר לעשות Constraint מהסוג

1
where T : ValueType

לפעמים אנחנו רוצים שType שנקבל יהיה דווקא value type ולא reference type

נוכל לכתוב את זה כך:

1
where T : struct

שימוש אפשרי:

1
2
3
4
5
public static T Clone<T>(T source)
where T : struct
{
return source;
}

הפונקציה הזאת מקבלת כמעט כל value type ומשכפלת את הערך שלו.

למשל

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public struct Person
{
public string Name;
public string LastName;
public Person(string name, string lastName)
{
Name = name;
LastName = lastName;
}
}
Person ziggy = new Person("Bob", "Marley");
Person bob = Clone(ziggy);
ziggy.Name = "Ziggy";
Console.WriteLine(bob.Name); // Prints Bob!

למה זה עובד? מאחר וכאשר מעבירים value type לפונקציה מועבר העתק שלו, הפונקציה מחזירה עותק של הערך שקיבלה.

באופן דומה קיים Constraint מקביל:

1
where T : class

המשמש כדי לדרוש שמחלקה תהיה reference type. (שימו לב, גם interfaceים, delegateים, Arrayים וכו’ נחשבים reference type).

למה זה טוב? כפי שציינו, כאשר מעבירים value type לפונקציה, מועבר עותק שלו. פעולה זו עשויה להיות כבדה, לכן לפעמים נרצה להכריח פונקציה לקבל רק reference types שאינם דורשים העתקה של כל האובייקט.

עוד סיבה אפשרית להשתמש בזה היא מאחר ובמידה ומועבר value type לא נוכל להשתמש במילה השמורה as, ראו גם טיפ מספר 12.

שבוע גנרי טוב

שתף