372. C# Annonymous class implementation

בהמשך לטיפים הקודמים, נראה כעת טכניקה לחקות את הקונספט של Anonymous Types בJava.

נניח שיש לנו ממשק כזה:

1
2
3
4
5
public interface IInvertibleConverter<TSource, TTarget>
{
TTarget ConvertFrom(TSource source);
TSource ConvertBack(TTarget target);
}

זה ממשק יחסית פשוט, שבד"כ המימושים שלו יראו בערך כך:

1
2
3
4
5
6
7
8
9
10
11
12
public class StringIntegerConverter : IInvertibleConverter<string, int>
{
public int ConvertFrom(string source)
{
return Convert.ToInt32(source);
}
public string ConvertBack(int target)
{
return Convert.ToString(target);
}
}

במידה ונשתמש במימוש הזה במקום אחד בלבד, זה מרגיש קצת בזבוז לכתוב בשבילו מחלקה.

במקרה כזה, נוכל לעשות טריק כזה:

נממש מחלקה כזאת:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
internal class AnonymousConverter<TSource, TTarget> : IInvertibleConverter<TSource, TTarget>
{
private readonly Func<TSource, TTarget> mConvertFrom;
private readonly Func<TTarget, TSource> mConvertBack;
public AnonymousConverter(Func<TSource, TTarget> convertFrom, Func<TTarget, TSource> convertBack)
{
mConvertFrom = convertFrom;
mConvertBack = convertBack;
}
public TTarget ConvertFrom(TSource source)
{
return mConvertFrom(source);
}
public TSource ConvertBack(TTarget target)
{
return mConvertBack(target);
}
}

היא מקבלת בConstructor שני Delegateים וקוראת להם במימושים של הפונקציות שלה.

ניצור פונקציה סטטית כזאת:

1
2
3
4
5
6
7
8
public static class InvertibleConverter
{
public static IInvertibleConverter<TSource, TTarget> Create<TSource,TTarget>
(Func<TSource, TTarget> convert, Func<TTarget,TSource> convertBack)
{
return new AnonymousConverter<TSource, TTarget>(convert, convertBack);
}
}

ואז נוכל להשתמש בה כך:

1
2
3
4
5
IInvertibleConverter<string, int> myConverter =
InvertibleConverter.Create<string, int>
(x => Convert.ToInt32(x), x => Convert.ToString(x));
string three = myConverter.ConvertBack(3);

כעקרון כאן זה נראה פחות יפה. זה בד"כ יפה אם אנחנו לא צריכים לציין פרמטרים גנריים וכו’, אבל העקרון הוא שבמידה ורוב המימושים שלנו הם יחסית פשוטים, ומשתמשים בהם במקום אחד (כלומר אין בהם Reuse), אז הדבר הזה יכול להיות מאוד נוח.

זה מחקה קצת את הסיפור של טיפוסים אנונימיים בJava.

סופ"ש אנונימי טוב.

שתף