DCSIMG
שמות Properties כמחרוזות - Ido Flatow's Blog Veni Vidi Scripsi

Ido Flatow's Blog

Veni Vidi Scripsi

News

Have you heard me speak?
Powered
<style type='text/css' media='screen' id='sm_css'> #smix {overflow: visible;height: auto;border-radius: 10px;max-width: 250px;background-color: #323232;text-align: left;font-size: 12px;line-height: 16px;font-family:'Lucida Sans Unicode','Lucida Grande',Verdana,Arial,Helvetica,sans-serif;-webkit-border-radius: 10px;-moz-border-radius: 10px;border-radius: 10px;} #smix a {color: #0056CC;text-decoration: none;} #smix .sm_head {color: #fff; line-height: 1em;font-size: 1.4em;padding: 10px;color: #fff;} #smix .sm_lanyard_wrapper {background-color: #fff;;clear: both;width: 97%;margin: 0 auto;margin-bottom: 0px;} #smix .sm_lanyard_content {padding: 7px;}#smix button.sm_rec, #smix a.sm_rec, #smix input[type=submit].sm_rec { padding: 6px 10px; -webkit-border-radius: 2px 2px;-moz-border-radius: 2px; border-radius: 2px; border: solid 1px rgb(153, 153, 153); background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 255, 255)), to(rgb(221, 221, 221))); color: #333; text-decoration: none; cursor: pointer; display: inline-block; text-align: center; text-shadow: 0px 1px 1px rgba(255,255,255,1); line-height: 1; }#smix .sm_rec:hover { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(248, 248, 248)), to(rgb(221, 221, 221))); }#smix .sm_rec:active { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(204, 204, 204)), to(rgb(221, 221, 221))); }#smix .sm_rec.medium { padding: 3px 7px; font-size: 13px; }#smix .sm_rec span.icon.thumbs_up {background-position: 0px 36px;vertical-align: text-top;display: inline-block;margin-right: 4px;height: 18px;width: 16px;background-image: url(http://speakermix.com/images/new/thumbsold.png);}#smix .sm_rec:hover span.icon.thumbs_up {background-position: 0px 18px;} #smix .sm_events {padding:2px 0px 4px 0px;} #smix .sm_section {font-size: 10px; border-bottom: 1px solid silver; margin-bottom: 6px;} #smix .sm_subline {font-size:120%;margin-top:4px;font-weight:bold} #smix .powered {text-align: right} #smix .powered img {margin: 7px} </style>
Sela Technology Center

Advertisement

שמות Properties כמחרוזות

ברצוננו לכתוב מתודה אשר תקבל שם קובץ חדש ורשימת קבצים בתיקייה ותחזיר שם קובץ תקין שאינו קיים בתיקייה (כמו שיצירת קובץ חדש בתיקייה תחת וינדוס יוצרת קבצים בשם "new", "new1", "new2" וכו').

string GetUniqueFileName(List<File> files, string newFileName)

נוכל לכתוב מתודה אשר עוברת על רשימת הקבצים בתיקייה (List כלשהו) ומחפשת עפ"י מאפיין שם קובץ (obj.FileName) אם השם תפוס ואם כן, להוסיף לשם שהועבר איזשהו Suffix ולנסות שוב עד למציאת שם תקין.

עכשיו בואו נסבך - נניח שאנחנו רוצים עוד מתודה שכזו, הפעם על רשימה אחרת והשוואה מול מאפיין בשם אחר. חלקנו יכתוב עוד מתודה (copy&paste+שינויים קטנים), אבל יש דרך אחרת - הפיכת המתודה לגנרית (על הטיפוס המוכל ב-List) והעברת שם ה-Property כמחרוזת.

string GetUniqueString<T>(List<T> items, string newItemValue, string comparedPropertyName)

במתודה החדשה נבצע איזשהי איטרציה (foreach / linq) ואת ההשוואה נעשה באמצעות Reflection על-מנת לקבל את הערך מאחורי ה-Property.

כמובן שכל מי שיצא לו לכתוב פתרון שכזה, היה צריך לתת את הדעת למצבים בהם המאפיין המבוקש אינו קיים, בין אם בגלל שגיאת כתיב בשם המחרוזת (דבר שניתן לרוב לגלות מהר תוך כדי הפיתוח) ובין אם בגלל באגים מתגלגלים כתוצאה מעדכון מבנה המחלקות (השמטה/שינוי של מאפיין) - באגים שיותר קשה לגלות ואשר לא פעם נגלים רק בשלב הבדיקות המאוחרות.

פתרון אחר אפשרי, למקרה שבו שמות המאפיינים ידועים בזמן הפיתוח (מתאים למקרה בו מבצעים Code Reuse כמו בדוגמה למעלה) הינו להשתמש ב-lambda expressions:

string GetUniqueString<T>(List<T> items, string newItemValue, Func<T, string> comparedProperty)

בקוד המתודה נשתמש ב-First על-מנת למצוא אם קיימים איברים כאלו ברשימה

if (items.First(i=>(comparedProperty(i) == newItemValue)) != null) ...

קריאה למתודה שכזו יכולה להראות כך:

string newFileName = GetUniqueString<File>(files, "new file", (f=>f.Name));

כך נוכל להבטיח ששם ה-Property הוא Strongly Types וכל שינוי במבנה המחלקה תגרום לשגיאת קומפילציה (בין אם שינוי שם המאפיין, מחיקתו ואפילו שינוי הטיפוס שלו).

כמובן שאפשר להרחיב מתודה זו, כך שהיא גם תדע לטפל במאפיינים שהם לאו דווקא מחרוזות ע"י הרחבת הגנריות ושימוש ב-Equals.

פתרון זה גם יכול להכתב באמצעות delegate שהרי lambdas הם מימוש של delegate, ולכן גם ניתן לתת פתרון לבעיה זו ב-2.0 net.

Comments

Ido Flatow said:

להלן בעיה - בהנתן Property כלשהו, נניח ששמו FirstName, עליכם להעביר למתודה את שם ה-Property כמחרוזת,

# August 4, 2008 5:59 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: