הקוד המשמעותי פה הוא
set { Type theType = typeof(T); MethodInfo myParser = theType.GetMethod("Parse", new Type[] { Type.GetType("System.String") }); object obj = Activator.CreateInstance(theType); _blahinfo = (T) myParser.Invoke(obj, new object[] { value.ToString() }); }
|
בשורה הראשונה יוצרים אובייקט Type, שפשוט מכיל מידע על הטיפוס הספציפי שtypeof מחזיר.בשורה השנייה יוצרים אובייקט MethodInfo שמכיל, כמו שהבנתם בטח, מידע על שיטה מסויימת ששייכת לטיפוס שמוכל בtheType.
היא מקבלת כפרמטרים את החתימה של השיטה: את השם שלה, במקרה הזה Parse, ומערך של Typeים שמכיל את סוגי הפרמטרים שהשיטה מקבלת, במקרה של Parse היא מקבלת רק string אחד.
יצרתי את המערך בתוך ההגדרה מטעמי אסטתיקה, כי בכל מקרה לא משתמשים בו אחר כך, לא פה ספציפית לפחות.
בשורה השלישית אני יוצר אובייקט מאותו מהסוג שמכיל את השיטה שאני רוצה, ההבדל היחיד הוא שהוא נוצר בזמן ריצה (זה נקרא Late Binding) ולא בזמן קומפלציה.
במקרה של Parse השיטה היא סטטית אז זה ממש לא משנה, בהמשך פשוט מתעלמים מהאובייקט הזה, אפשר פשוט להגדיר אותו כnull כדי להקטין תקורה (למרות שאני חושב שבמקרה הזה זה נחשב כאילו אין רפרנס בכלל לאובייקט הזה והוא נמחק ע"י הGC)
ולבסוף, בשורה האחרונה אני מסיים את הset בקאסט לטיפוס הג'נרי לobject שהשיטה Invoke מחזירה.
השיטה Invoke שייכת לאובייקט MethodInfo ומקבלת את האובייקט שיקרא לשיטה, אבל כפי שכתבתי קודם מכיוון שParse היא מתודה סטטית האובייקט הזה לא משמש לכלום, והיא מקבלת כפרמטר השני מערך של objectים שמכיל את הערכים שמועברים לפונקציה. לא להתבלבל, ההגדרה בשורה השנייה מכילה את המידע על הטיפוסים שהפונקציה מקבלת, כלומר החתימה שלה, ההגדרה בשורה הרביעית מכילה את הערכים שמועברים!
גם פה מטעמי אסתטיקה יצרתי את המערך כבר בתוך ההגדרה.
value מומר פה לstring מכיוון שאי אפשר לעשות המרה לא מפורשת בין object לstring.
זהו.
כל הדבר הזה פחות או יותר מקביל ללכתוב
_blahinfo=T.Parse(value.ToString());
|
אבל זה לא אפשרי לצערנו חח
