אמנם כתבתי בפעם הקודמת שזה כנראה הפוסט האחרון בסדרה, אבל מאחר וחשבתי על עוד איזשהו רעיון, להלן עוד טיפ על מימוש Fluent Syntax.
ראינו בעבר כי אחד הדברים השימושיים והיפים בC# הוא היכולת להוסיף Extension Methods לInterfaces (טיפ מספר 84).
מה שאולי לא טריוויאלי הוא העובדה שאפשר לנצל עובדה זו גם עבור Fluent syntax:
נניח שיש לנו את הFluent Syntax הטיפ מסובך שיצרנו בחלק 2.5 של הסדרה:
|
|
נוכל להוסיף Extension Method לInterfaceים. לדוגמה, יש לנו את הפונקציה WithColumn שיוצרת לנו עמודה באיזשהו שם וטיפוס. יש לנו את הפונקציה MakePrimaryKey שהופכת את העמודה גם להיות Primary Key של הטבלה.
נוכל ליצור איזשהי פונקציה שמאחדת אותם:
|
|
ואז נוכל לכתוב דברים כאלה:
|
|
וכאלה:
|
|
אבל למרבה הצער לא כאלה:
|
|
למה זה בעצם לא מתקמפל? הסיבה לכך היא שמאחר והטיפוס IQ2 הוא בעל פרמטר גנרי, יש בידינו שתי אפשרויות: או שכל הטיפוסים יזוהו ע"י הקומפיילר בזמן קימפול באופן Implicitly, או שאנחנו נציין Explicitly את כל הפרמטרים בזמן קימפול.
מאחר ויש כאן פרמטר שלא יכול להיות מזוהה בזמן קימפול באופן Implicitly (זה הפרמטר בשם T), עלינו לציין את כל הפרמטרים בזמן קימפול באופן Explicitly.
פתרון אפשרי לבעיה יכול להיות למשל שIQ2 ירש מטיפוס לא גנרי (למשל IQ1).
(כנראה זה הפתרון הנכון, וגם עדיף שIQ4 יירש מIQ1, ככה גם יהיה לנו רק Extension Method בודד, במקום 3 שצוינו מעלה)
השאלה היא האם הדבר הזה טוב? למה צריך את זה בכלל? מצד אחד זה טוב, מאחר וזה מאפשר לנו להוסיף עוד Syntax לFluent Syntax קיים וכך לעשות את הFluent Syntax אפילו טוב יותר!
מצד שני, זה יכול להיות קשה להוסיף Fluent Syntax משלנו (למשל, אולי נצטרך להוסיף עוד ממשקים/מחלקות), ואם הFluent Syntax כבר שייך לנו, אז מה אכפת לנו להוסיף לו כבר עוד פונקציות?
לדעתי אין תשובה חד משמעית. אם הFluent Syntax לא שייך לנו (למשל שייך לאיזשהו Open Source כמו Rhino Mocks או Ninject), אז הדבר הזה מאפשר לנו להרחיב את הSyntax כך שיתאים לצרכים שלנו. אם הSyntax שייך לנו, אין לזה כל כך יתרון מלהוסיף את הפעולות הרלוונטיות לממשקים של הSyntax, אבל אולי זה בכל זאת יכול להתאים: למשל, במקרה כאן, כל מי שאי פעם ירש מהממשקים שציינתי כאן, יקבל חינם את הפונקציהWithPrimaryKeyColumn, כך שאולי זה כן שווה את זה…
בכל מקרה, זה נחמד.
המשך יום צף טוב!