ConverterSmak NR.3Przerobiliśmy 3 z 5 szablonów gotowych generycznych delegat. Zostały nam jeszcze dwa. A w tym wpisie opiszę delegatę Converter.
Nie ma w niej niczego specjalnego. Jest to kolejna delegata, która istnieje z powodu starego kodu .NET 2.0 sprzed LINQ.
Celem tej delegaty jest przekonwertowanie jednego obiektu w drugi. Od razu rodzi się pytanie po co używać do tego oddzielnej delegaty gdy mamy delegatę Func.
Odpowiedź jest prosta obecnie byśmy użyli delegaty Func do tworzenia wskaźnika do metod konwertujących obiekty.
Niestety wcześniej tak nie było.
Delegata Converter urodziła się po to by dać kolekcjom Array i List<T> możliwość bezpiecznej konwersji z jednej kolekcji elementów do takiej samej kolekcji innych elementów.
Sama delegata Convert<> nie spełnia żadnej funkcji. Tak jak ustaliśmy wcześniej nawet gdybyś chciał użyć podobnej delegaty w celach konwersji to raczej byś użyć delegaty Func<TInput,TOutpu>.
Converter<Person, string> personToString = p.Convert;
Func<Person, string> personToStringFunc = p.Convert;
Chodzi o używanie metod jak ConverterAll.
Oto przykład użycia tej metody.
static void Main(string[] args)
{
Program p = new Program();
List<Person> lstPeople = new List<Person>
{
new Person(){ Name = "Tomek", Age = 23},
new Person(){ Name = "Franko", Age = 21},
new Person(){ Name = "Doman", Age = 18},
new Person(){ Name = "Alicja", Age = 19},
};
Converter<Person, string> personToString = p.Convert;
List<string> lis = lstPeople.ConvertAll(personToString);
}
public string Convert(Person per)
{
return per.Name + " " + per.Age;
}
Powyższy kod przetłumaczy kolekcję osób na kolekcję napisów. Oczywiście teraz gdy mamy wyrażenie lambda nie ma powodu by jawnie deklarować delegatę Converter.
List<string> s = lstPeople.ConvertAll(k => k.Name + " " + k.Age);
Warto zaznaczyć, że powyższe wyrażenie jest równe metodzie LINQ Select.
Ona daje więcej możliwości co by tłumaczyło dlaczego obecnie nikt by nie używał metody ConvertAll().
List<string> s = lstPeople.Select(k => k.Name + " " + k.Age).ToList();
List<double> ages = lstPeople.Select(k => (double)k.Age).ToList();
Różnica pomiędzy metodą ConvertAll i Select polega na tym ,że metody LINQ mają wstrzymaną egzekucję.
Oznacza to, że konwersja nastąpi dopiero wtedy gdy kolekcja po transformacji będzie potrzebna.
Generalnie nowa składnia LINQ jest preferowana. Metody jak ConvertAll() dla Array i List<T> wciąż są dostępne dla kompatybilności podobnie jak sama delegata Converter.
Nie ma jednak sensu jej używać w swoim kodzie.