Przykłady wykorzystania mechanizmu metod rozszerzających w C# 3.0
Metody rozszerzające są nową cechą języka C# 3.0. Pozwalają one rozszerzać istniejące typy (klasy i struktury) o nowe metody. Nie ma, niestety, możliwości dodawania nowych własności, ale to co jest i tak pozwala na ciekawe eksperymenty z własnymi DSLami (językami specyficznymi dla domeny).
Aby zdefiniować rozszerzenie metod, należy:
- zdefiniować klasę statyczną (o dowolnej nazwie),
- wewnątrz tej klasy zdefiniować statyczną metodę, która jako pierwszy parametr przyjmuje parmetr o sygnaturze: this TypRozszerzany instancja.
Potem metodę taką można wykonać na każdej instancji danej klasy identycznie jak metody wbudowane.
W niniejszym artykule podane zostaną dwa krótkie i proste przykłady jak korzystając z metod rozszerzających zaimplementować cukierki składniowe znane z języka Ruby oraz platformy Ruby on Rails.
1. Metoda Do.
Sposób 1 - przez obiekt proxy
Rozszerzenie
public delegate void VoidFunc<T>(T arg); public class TimesProxy { public TimesProxy(int initNumber) { number = initNumber; } public void Do(VoidFunc<int> block) { for(int i = 0 ; i < number ; ++i) { block(i); } } private int number; } public static class IntegerExtensions1 { public static TimesProxy Times(this int number) { return new TimesProxy(number); } }
Wykorzystanie
12.Times().Do( (i) => Console.WriteLine(i)) ;
Sposób 2 - bezpośrednio przez metodę
Rozszerzenie
public delegate void VoidFunc<T>(T arg); public static class IntegerExtensions2 { public static void TimesDo(this int number, VoidFunc<int> block) { for (int i = 0; i < number; ++i) { block(i); } } }
Wykorzystanie
12.TimesDo( (i) => Console.WriteLine(i) );
2. Rozszerzenia dla daty i czasu
Rozszerzenie
public static class DateTimeIntegerExtensions { public static TimeSpan Days(this int numOfDays) { return TimeSpan.FromDays(numOfDays); } public static TimeSpan Hours(this int numOfHours) { return TimeSpan.FromHours(numOfHours); } public static TimeSpan Minutes(this int numOfMinutes) { return TimeSpan.FromMinutes(numOfMinutes); } } public static class DateTimeExtensions { public static DateTime Ago(this TimeSpan timeSpan) { return DateTime.Now - timeSpan; } }
Wykorzystanie
DateTime someTimeAgo = DateTime.Now - (10.Days() + 4.Hours() + 35.Minutes());
if (someTimeAgo < 12.Days().Ago())
{
Console.WriteLine("Earlier than 12 days ago");
}
else
{
Console.WriteLine("Later than 12 days ago");
}
wersja strony: 8, ostatnia edycja: 04 Feb 2009 18:19