Feature מסוים שאין לנו תמיכה בו בC# הוא לשים Constraintים על פרמטרים גנריים כך שירשו מהטיפוסים Array, Enum, Delegate או ValueType.
(ראו גם טיפ מספר 29)
תכלס, בשביל שני האחרונים אפשר להסתדר: במקום ValueType, אפשר לכתוב
|
|
(ראו גם טיפ מספר 31)
ובמקום Array, אפשר לדאוג שהפונקציה תקבל T[] (או אולי T[,] או T[,,] וכו’, תלוי במימד של המערך)
עם זאת, השניים הראשונים לפעמים מתבקשים. עשינו בעבר מספר טריקים, למשל שמנו Constraint ש
|
|
כדי לצמצם את מספר האפשרויות שישלחו טיפוס שהוא לא Enum.
(ראו גם טיפים מספר 72, 209)
מסתבר שבאופן כללי, הCLR דווקא כן תומך בFeature הזה. אם תקחו קוד IL עם Constraint רגיל, ותשנו את הIL שהטיפוס שממנו יורש T הוא Enum, זה דווקא יעבוד לכם! (כלומר, אם תוסיפו Reference לDLL הזה, באמת תהיה לכם את האכיפה)
מישהו מצא באינטרנט Hack מתוחכם בשפה המאפשר להשתמש בConstraint הזה בכל זאת:
השימוש הוא באמצעות Naked Constraints (ראו גם טיפ מספר 34) ונראה ככה:
|
|
כעת אפשר לעשות משהו כזה:
|
|
ככה תהיה ואלידיאציה בזמן קימפול:
|
|
הקוד הבא עם זאת, לא יתקמפל:
|
|
הדבר הזה אמור לעבוד גם על Delegateים, אבל לא ניסיתי את זה.
בכל מקרה זה בעיקר מגניב, אבל לא הייתי ממליץ לאף אחד ליצור מחלקת ביניים בשביל הFeature הזה.
(אלא אם כן יש לכם סיבה ממש ממש ממש טובה, וכנראה אין לכם)
שימו לב שזה לא מאפשר לנו לעשות Extension Methods לEnum, כי אנחנו צריכים פה ירושה, ואין ירושה במחלקות סטטיות. גם אם הייתה, זה היה בלתי אפשרי, מאחר ולא ניתן להגדיר Extension Methods במחלקות גנריות סטטיות.
הפתרון הזה נמצא ע"י אחד המנהלים מStackOverflow עם הכינוי SLaks
המשך יום מלא Enumים בטוחים טוב!