363. DebuggerTypeProxy

[נכתב ע”י גיא דוברובסקי]

בוקר טוב,

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

החלטתי לעזור קצת לזלינגר ולתרום את חלקי לפורום בדמות הופעת אורח.

אתם מוזמנים לשלוח גם טיפים יומיים כדי שנעשה את הפורום הזה פעיל ופורה יותר – for us by us.

ובכן, אחרי ההקדמה הקצרה,

הטיפ היומי הוא בנושא DebuggerTypeProxy.

מה זה ולמה זה טוב?

קרה לכם פעם שדיבגתם אוביקטים של טיפוסים מורכבים?

כנראה שכן אחרת לא הייתם מנויים על הטיפ היומי.

קרה לכם שבשביל להגיע לפיסת המידע שאתם מחפשים, הייתם צריכים לחפור עמוק בתוך האוביקט?

לי זה קרה המון פעמים, ויותר מזה, אני תמיד מחפש את אותה פיסת המידע.

קרה לכם שבעת דיבוג הופיע לכם מלא זבל שלא באמת מעניין אותכם?

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

אם התשובות שלכם היו חיוביות לשאלות הנ”ל, תמצאו את הטיפ הזה מועיל מאוד:

DebuggerTypeProxy הינו attribute אשר מגדיר איך יראה האוביקט בזמן דיבאג.

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

  • פריטי המידע הרלוונטיים לא נוחים לגישה
  • רוצים להחביא פריטי מידע לא רלונטיים

טוב מראה עיניים ממשמע אוזניים:

יש לנו את הטיפוס Student (כאשר מה שיעניין אותנו בו בזמן דיבאג הוא רק השם שלו והציונים):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Student
{
public Student(string name)
{
_name = name;
_grades = new Dictionary<string, int>();
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private Dictionary<string, int> _grades;
public Dictionary<string, int> Grades
{
get { return _grades; }
set { _grades = value; }
}
private string _unimportantDetail;
public string UnimportantDetail
{
get { return _unimportantDetail; }
set { _unimportantDetail = value; }
}
private string _anotherBoringFact;
public string AnotherBoringFact
{
get { return _anotherBoringFact; }
set { _anotherBoringFact = value; }
}
}

ניצור instance של Student ונראה ונסתכל עליו בדיבאג:

1
2
3
4
5
6
7
8
Student dubrovski = new Student("Dubrovski");
dubrovski.Grades.Add("Infi", 80);
dubrovski.Grades.Add("Combi", 90);
dubrovski.Grades.Add("Tennis", 100);
dubrovski.UnimportantDetail = "some unimportant garbage that is not relevant for debugging";
dubrovski.AnotherBoringFact = "some boring info that is not relevant for debugging";
363_1.jpg

בעיות:

  • לא רואים את הציונים – בשביל לראות אותם צריך לפתוח Grades ולהתסכל על כל פריט במילון
  • הצפה במידע לא מעניין – בזמן דיבאג אני יודע שיש פריטים שאני לא רוצה לראות.

נפתור זאת ע"י יצירית DebuggerTypeProxy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class StudentDebuggerTypeProxy
{
private Student _student;
public StudentDebuggerTypeProxy(Student student)
{
_student = student;
}
public string Name
{
get
{
return _student.Name;
}
}
public string Grades
{
get
{
IEnumerable<string> flatGrades =
_student.Grades.Select(item => item.Key + ":" + item.Value);
return String.Join(", ", flatGrades);
}
}
}

במחלקה זאת אנחנו פותרים את הבעיות לעיל ע"י:

  • הגדרת אופן תצוגת הציונים - בחרתי לשרשר אותם
  • חשיפת רק פריטי המידע הרלונטיים: בחרתי לא להציג את:
    • UnImportantDetail
    • AnotherBoringFact

הפעלת ה attribute שיצרנו תהיה באופן הבא:

1
2
3
4
5
[DebuggerTypeProxy(typeof(StudentDebuggerTypeProxy))]
class Student
{
// ...
}

וכעת בעת דיבוג של אוביקט מטיפוס Student, הוא יראה לנו בצורה הבאה:
363_2.jpg

כמובן שנוכל תמיד לראות את האוביקט המקורי ע"י בחירת Raw View:
363_3.jpg

דיבוג יעיל.

שתף