
GetFields מחזיר מערך של FieldInfo לכל השדות. כברירת מחדל לא מוחזרים שדות פרטיים, ולכן השדה age לא הופיע בהדגמה הראשונה.GetProperties מחזיר את התכונות. בהדגמה הופיעה רק התכונה age, כי היא היחידה שחשופה.GetConstructors מחזיר את הבנאים. בהדגמה הופיעו שני בנאים: בנאי ריק ובנאי עם שני מחרוזות ומספר.GetMethods מחזיר את כל השיטות, כולל אלה שהגיעו מהטיפוס Object: ToString, Equals, GetHashCode ו-GetType. תכונה מומרת על ידי הקומפיילר לשתי שיטות, get ו-set, וזה מופיע בתוצאה.GetMembers מחזיר את כל החברים בבת אחת.Activator.CreateInstance מקבל את שם ה-Assembly ואת שם הטיפוס. התוצאה היא ObjectHandle, ו-Unwrap מחזיר את האובייקט עצמו.SetValue על FieldInfo או PropertyInfo דורש לציין את האובייקט שאליו מכניסים את הערך. ל-PropertyInfo של אינדקסר מעבירים null במקום אינדקס.Invoke על MethodInfo מקבל את האובייקט ואת רשימת הפרמטרים.הטקסט המלא של הדקות הראשונות בהרצאה «Reflection - חלק 2» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אוקיי, קודם כל יש לנו כאן טייפ ואנחנו רוצים טייפ לגבי פרסון. בואו נלך ונבנה פה את קלאס פרסון ובקלאס פרסון נגדיר את הדברים הבאים public string first name last name private int underline age public int age עם a גדולה שהולך להיות פרופרטי
יש לפרופרטי הזה את חלק הגט שמחזיר את underline age ויש לפורפרטי הזה את חלק ה-set, מבצע בדיקה. האם ה-value שאנחנו מנסים להכניס אכן הוא חוקי?
האם הוא גדול שווה לאפס? ורק אם הוא חוקי, אנחנו מכניסים אותו ל-underline h. יש לנו כאן קונסטרקטור דרק, קונסטרקטור שמקבל את שלושת ה-data members, first name, last name, h, ומבצע השמה שלהם.
first name מקבל את ה-first name, אהלן last name ו-age חייב לעבור דרך ה-property בכדי לבצע את הבדיקה. בנוסף יש לנו כאן פונקציה שמציגה את הפרטים, נציג first name, נציג last name, נשנה פה את ההדפסה ונציג את ה-age וכעת בנינו את המחלקה person שיש לה גם data members,
גם property, גם קונסטרקטורים וגם מתודות. אוקיי, איך זה נקרא? DataMember נקרא Field, מאפיין נקרא Property.
כל הקונסטרקטורים נקראים קונסטרקטורס, ומתודה זה Method. כל אלה מונחים של Object Oriented שאנחנו כבר מכירים.
אבל בכוונה הגדרתי אותם שוב, כי אנחנו הולכים עכשיו לקרוא את ערכם. אז יש לנו פה את הטייפ P, ועכשיו אנחנו יכולים לגשת ל-T נקודה ועל ידי פונקציות ה-Get לקבל את כל מה שאנחנו רוצים בעצם.
לדוגמה בואו נתחיל עם ה-Fields. אנחנו יכולים לקבל נתונים לגבי פילד בודד, כמובן אנחנו צריכים לתת את ה-שם שלו, פה אנחנו רואים שנתנו את ה-Name, אנחנו צריכים לקבל את ה-Name, לשלוח את ה-Name ליתר דיוק, או GetFields נותן לנו נתונים לגבי כל ה-Fields.
GetFields מחזיר אובייקט מסוג FieldInfo, אינפורמציה לגבי פילד בודד, כאשר פילד כאמור זה DataMember, כלומר משתנה ברמת מחלקה. getField מחזיר לנו אותו הדבר אבל מערך חד-ממדי fieldInfo סוגריים מרובעים בואו נקרא את כל ה-fields אז כל מה שאנחנו צריכים לעשות זה לקרוא ל-getFields
לקבל fieldInfo שימו לב שזה נמצא במרחב השמות System Reflection זה כאמור מערך חד-ממדי ואנחנו יכולים לגשת ולבצע הדפסה של כל ה-fields נרוץ ב-foreach, field info, in fields ופשוט נציג את הפריט עצמו ונראה מה מוצג כאשר אנחנו מריצים את התוכנית.
אז אנחנו רואים שיש לנו כרגע רק את ה-first name ואת ה-last name. איפה ה-age? הרי קיים לנו data member שנקרא age, זה בהחלט field, אז by default לא חוזרים לנו ערכים שהם private.
ואנחנו יכולים להתגבר על הסיטואציה הזאת וגם לראות ערכים שהם פרייבט אנחנו נתעסק עם זה עוד מעט. אבל מה בקשר לדברים נוספים? אלה היו ה-Fields.
מה בקשר ל-Properties? יש לנו PropertyInfo. ניקח את כל ה-Properties, t.getProperties. גם כאן ראינו יש לנו אפשרות להשיג את כל ה-Properties או Property אחד ספציפי.
בואו ניגש ונביא את כל ה-Properties, נציג את רשימת ה-Properties, רופרטי אינפו נרוץ על הפרופרטיז ואנחנו מציגים את הפרופרטיז עצמם, בואו נריץ ונראה שיש לנו רק פרופרטי אחד ויחיד שנקרא age והוא מחזיר לנו אינטג'ר שזה int32. קונסטרקטורים זה הדבר הבא בתור שיש לנו, קונסטרקטור אינפו מתאר לנו את הקונסטרקטורים וניחשתם נכון get
קונסטרקטור בודד או קונסטרקטורי בואו נקבל את כל הקונסטרקטורים שיש לנו נציג את כל הקונסטרקטורים for each constructor info in constructors נריץ את זה ויש לנו כעת שני קונסטרקטורים שאנחנו רואים שהם קיימים אחלה קונסטרקטור אחד ריק קונסטרקטור אחד שמקבל סטרינג סטרינג ואינט מתודות method info או get method אחת ויחידה או get methods בואו
נקרא ל get methods נרוץ על כל המתודות ושימו לב שיש לנו הרבה יותר מתודות ממה שקיימות במחלקה פרסון.
אז למה יש לנו כל כך הרבה מתודות? בואו נסתכל רגע על המחלקה פרסון עצמה, ונראה שבמחלקה פרסון קיימת לנו מתודה אחת ויחידה שנקראת פרינט.
אם אנחנו נריץ את זה, אנחנו הולכים לראות שיש לנו איזושהי מתודה שנקראת get_h ומתודה שנקראת set_h. אלו כאמור מתודות שמייצגות את ה-property h.
יודעים שproperty מוחלף על ידי הקומפיילר לשתי מתודות get וset והנה אנחנו רואים אותם כאן. זאת אומרת מה שקיים בעצם באמת בפועל בתוך קוד ה-NSI-L זה ה-get וה-set האלה כמתודות.
אוקיי, הנה הפרינט שלנו אבל מהם ארבעת הפונקציות שאנחנו רואים כאן? אז אלה פונקציות שהגיעו כמובן מהמחלקה שירשנו.
אנחנו ירשנו את Object ולכן יש לנו פה את 2String, Equals, GetHashCode ו-GetType. ארבעת אלה הגיעו אלינו מ-Object ולכן אנחנו רואים אותם בסדרת הפונקציות ששייכות ל-Person.
הדבר הבא שאנחנו יכולים להשיג זה משהו שנקרא MemberInfo. כאן, שוב פעם יש לנו מרמר בודד או GetAllMembers. אז מה זה?
Member. Member זה כל דבר שנמצא בתוך Person. זה יהיה Fields, Properties, Constructors, Methods וכולי. בואו נרוץ ב-For each, Member info, נציג רק לפני שאנחנו הולכים לצפות בכל ה-Members, נריץ ונראה שעכשיו אנחנו רואים גם את הפונקציות,
גם את ה... עד לכאן זה הפונקציות, יש לנו פה את ה-Setors, יש לנו פה את ה-Property והנה יש לנו פה את ה-Fields, הכל ביחד כאשר אנחנו קוראים עם Get Members.
שימו לב שגם כאן לא קיבלנו ערכים שהם פרייבט, אנחנו כמובן הולכים לטפל בזה בהמשך. אז בדוגמה הזאת ראינו איך אנחנו יכולים לקרוא מידע לא רק של המחלקה פרסון, אלא גם דברים שנמצאים בתוך המחלקה פרסון.
אז בדוגמה הקודמת ובדוגמה הזאת קראנו נתונים ורק הצגנו אותם. אם אנחנו רוצים במהלך הריצה לחקור את המידע ולראות מה יש בתוך טיפוס מסוים, ככה אנחנו עושים את זה.
בואו נראה או נחשוב על איזושהי דוגמה שנרצה לעשות את הדבר הזה. יכולת מצב שאנחנו מקבלים איזשהו אובייקט ואנחנו רוצים לקרוא אותו ולפי המידע שיש בו לגשת לדאטאבס לטבלה מסוימת או ליתר דיוק לפי המידע שהוא בנוי ממנו.
אם יש לו פרופרטי שנקרא אימייל אנחנו רוצים לשמור אותו בטבלת אימיילס. אם יש לו פרופרטי שנקרא salary אנחנו רוצים לשמור אותו בטבלת העובדים. אז אם אנחנו רוצים את היכולת הזאת במהלך הריצה להבין מה ה-properties או ה-fields או ה-methods שיש בתוך האובייקט, ככה אנחנו יכולים לקרוא אותם.
אז זאת היא בעצם דוגמה אחת לשימוש ב-reflection. אנחנו הולכים לראות דוגמה נוספת לשימוש ב-reflection, והדוגמה הזאת בכלל עושה משהו אחר.
יכול להיות שיש מצב שבו אנחנו מקבלים איזשהו DLL במהלך הריצה של התוכנית, באופן דינמי, ביחד עם ה-DLL הזה אומרים לנו בדיוק איך ה-DLL נקרא, איך המחלקה שיש בו, המחלקות שיש בו נקראות, איזה שדות, פונקציות, data members, properties, constructors וכו' קיימים שם, אבל מה שאנחנו לא יודעים או שמה שאין לנו זה אין לנו את ה-DLL כאשר אנחנו בונים את האפליקציה.
זאת אומרת, איך אנחנו יכולים לבנות אפליקציה שאמורה לדעת רק כאשר היא רצה על קיומו של איזשהו DLL מסוים ששולחים לה באופן דינמי, ובמהלך חיי האפליקציה אין את ה-DLL הזה, או ליתר דיוק במהלך הפיתוח אין לנו את ה-DLL.
למעשה יש נישה בשוק שמשתמשת עם הקונספט הזה, זה קורה לעיתים נדירות אבל זה קיים בעולם, שבו רק במהלך הריצה אנחנו יודעים על קיומו של טיפוס נתונים, כן אומרים לנו את השמות, כי הרי אנחנו לא יכולים לשים את שם מוישה בתוך first name אם אנחנו לא יודעים שקיים שם משתנה first name כי יכול להיות שיש שם הרבה הרבה משתנים.
אז צריכים להגיד לנו תקשיב יש מחלקה שנקראת person ויש לה field שנקרא first name ויש לה פונקציה שנקראת print ואנחנו רוצים שתיצור אובייקט ממנה תכניס את מוישה לתוך first name ותקרא לפונקציית print.
כל הדבר הזה בצורה דינמית לחלוטין מבלי שיש לנו את המחלקה person בזמן הפיתוח. רק כאשר האפליקציה אצל הלקוח, רק אז דינמית האפליקציה מקבלת dll וצריכה לטעון את הdll ולהשתמש בטיפוסים שלו.
אז הדבר הזה גם ניתן לביצוע על ידי reflection. בואו נראה איך אנחנו יכולים לעשות את זה. דבר ראשון ניקח את המחלקה person שכבר כתבנו ונייצר dll ונכניס את המחלקה הזאת בתוך ה-dll.
נסגור את האפליקציה הנוכחית, נלך ונבנה פרויקט חדש, ניקח class library ונניח אנחנו בונים dll שנקרא business logic, זה בעצם אישויות שאנחנו רוצים להשתמש בהן באפליקציה שלנו.
נפתח את ה-dll הזה, במקום המחלקה class1 נדביק את המחלקה person, נלך ונשנה גם את הקובץ במקום קלאס אחד נקרא לו person.cs רק בכדי שיהיה הגיוני.
נבצע ריבילד עבור הסולושן ונראה שהוא כותב פה למטה ריבילד אול סקסידד אפשר להיפטר פה מכל מיני מרחבי שמות. סבבה והנה יש לנו כאן איזושהי מחלקה בתוך dll אפילו נגדיר אותה פה כפאבליק למרות שלא היינו חייבים.
ואנחנו רוצים לכתוב תוכנית בכלל אחרת לגמרי שלא מכירה את ה-DLL הזה במהלך הפיתוח אלא רק במהלך הריצה. לצורך הדוגמה בואו נבצע סגירה ונפתח פרויקט חדש.
כאן אנחנו רוצים מחלקה שמבצעת שימוש דינמי ב-DLL. זה יהיה Console Application ואנחנו לא רוצים לבצע Add Reference ל-Dלל כי אנחנו לא אמורים לדעת על קיומו.
רק כאשר התוכנית רצה אנחנו אמורים לדעת על קיומו של ה-DLL הזה. אוקיי, אז איך אנחנו בעצם דרך Reflection יכולים ליצור Object Person אם כרגע אין לי את ה-DLL הזה?
אז מה שצריך להיות לי זה כל מיני שמות.