67. How do extension methods work

ראינו בפעם הקודמת מה זה Extension methods.

ייתכן ועדיין לא השתכנעו למה זה טוב, אבל אנחנו נראה הרבה מאוד דוגמאות שיוכיחו לנו – זה אכן טוב.

היום נראה איך Extension Methods בעצם ממומשים.

בין C# 2.0 לC# 3.0 לא השתנה הCLR ולכן קריאה לExtension Method היא בעצם syntactic sugar למשהו שמוכר לנו:

קריאה סטטית prefixית של המשתנה.

עם זאת, אפשר לשאול במקום איך הקומפיילר יודע איזה מתודות הן Extension methods ואיזה הן לא, שהרי לא לכל מתודה סטטית ניתן לקרוא בצורה postfixית.

את התשובה נמצא, כמובן, בעזרת הReflector:

מבט חטוף בReflector על הIL של הExtension Method שכתבנו אתמול מניב את התוצאה הבאה:

1
2
3
4
.method public hidebysig static string Reverse(string givenString) cil managed
{
.custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
}

אמנם קשה להבין מזה משהו, אבל בעצם מוצמד למתודה שלנו Attribute מהסוג System.Runtime.CompilerServices.ExtensionAttribute:

זהו Attribute שאומר לקומפיילר שהמתודה שלנו היא בעצם Extension Method.

עם זאת, אם ננסה לכתוב קוד כזה במקום מה שכתבנו:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Extension]
public static string Reverse(string givenString)
{
List<char> reverseChars =
new List<char>(givenString.Length);
foreach (char currentChar in givenString)
{
reverseChars.Insert(0, currentChar);
}
return new string(reverseChars.ToArray());
}

נקבל בזמן קימפול את השגיאה הבאה:

Do not use ‘System.Runtime.CompilerServices.ExtensionAttribute’. Use the ‘this’ keyword instead.

כלומר, בעצם רק הקומפיילר רשאי להצמיד לנו את הAttribute הזה.

זה די מבאס למען האמת. נתקלתי בבעיה כזו בעת חילול מחלקות בCodeDom, ורציתי לחולל בין השאר גם Extension Methods.

למרבה הצער, CodeDom תומך בC# 2.0 (גם לא בצורה מלאה), לכן חשבתי שאוכל להשתמש בשיטה זו כדי להוסיף את הAttribute ולקבל קוד שמתנהג כמוExtension Methods.

עם זאת, לא ניתן לקמפל קוד כזה בעצמנו, ולכן נאלצתי להסתפק בפתרון אחר.

המשך יום מורחב טוב

שתף