163. System Attribute

עד כה ראינו כיצד ניתן לקרוא Metadata של טיפוסים ומתודות.

לפעמים אנחנו מעוניינים להוסיף Metadata משלנו לטיפוסים ומתודות. לדוגמה, נניח שיש לנו instance של מחלקה ואנחנו מעוניינים לייצר ייצוג Stringי שלה בצורה דינאמית, ע”י הדפסת הערכים של כל הProperties שהיא מכילה.

נוכל לעשות את זה בצורה הבאה:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static string ToString(object instance)
{
Type instanceType = instance.GetType();
PropertyInfo[] properties = instanceType.GetProperties();
List<string> propertiesValues = new List<string>();
foreach (PropertyInfo property in properties)
{
object propertyValue =
property.GetValue(instance, null);
propertiesValues.Add(string.Format("{0}={1}",
property.Name,
propertyValue));
}
return string.Join(Environment.NewLine,
propertiesValues.ToArray());
}

עכשיו, נניח שאנחנו רוצים להדפיס רק חלק מהProperties. איך נוכל להחליט איזה Property להדפיס ואיזה לא?

אפשרות אחת היא לפי קונבנציה – רק Properties שהשם שלהם לפי קונבנציה מסוימת, למשל מסתיים בPrintable יודפסו. אלא, שזה מלכלך לנו את הקוד.

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


כמובן, זו דוגמה אחת מתוך רבות לסיבה שאנחנו עלולים לרצות להוסיף מידע לMetadata שלנו.

למזלנו, השפה מאפשרת לנו לעשות דבר כזה, זאת באמצעות מושג שנקרא Attribute.

Attribute הוא בעצם טיפוס שיורש מהמחלקה Attribute. מה שמיוחד בו זה שאנחנו יכולים לשים אותו מעל Memberים שלנו וכך "לקשט" אותם.

למשל קיים הAttribute ששמו SerializableAttribute. Attribute זה ניתן לשים מעל מחלקות וכך לציין שמחלקה כלשהי ניתן לסריאליזציה.

איך זה נראה?

1
2
[SerializableAttribute()]
public class Person

קצת הסבר: בתוך הסוגריים המרובעים אנחנו מאתחלים את הAttribute. זאת ע"י קריאה לConstructor הדיפולטי – אלה הסוגריים המצוינים העגולים. שימו לב שאין צורך בקריאה לאופרטור new , אלא זה מתבצע בצורה אוטומטית.

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

ונזכור את כולם

שתף