Delegaty - używacie ich?

1

Cześć. Mam takie pytanie bardzo proste - Czy używacie delegatów w C#?
Tzn. rozumiem, że raz na jakiś czas mogą się przydać, ale czy używacie ich np w chociaż 30% Waszych projektów?

Pytam, ponieważ ja ich nie używam praktycznie wcale (może tylko kilka razy), a to z kilku powodów (mniej czytelny kod itd.).
A jak Wy do tego podchodzicie? Pytam, gdyż jestem ciekaw czy tylko ja mam taki "problem", czy może większość ludzi uważa delegaty za twór przydatny tylko w niewielu sytuacjach?

Pozdrawiam.

2

Delegaty są silnie związane z Eventami, a zatem używam delegatów dość często.

Poza tym, od kiedy weszła lambda expression, wg mnie użycie delegatów znacząco wzrosło. Sam zresztą, gdy widzę, że mogę wyciągnąć jakąś część kodu (bardzo często jest to np. pętla), która operuje na tym samym zestawie danych, ale z innym "ciałem" metody - wtedy tworzę nową metodę, która jako parametr przyjmuje np. Action

2

Jak wspomniał Jonathan - delegaty są związane z Eventami. Ale to mało...

Pytam, ponieważ ja ich nie używam praktycznie wcale (może tylko kilka razy), a to z kilku powodów (mniej czytelny kod itd.).
A jak Wy do tego podchodzicie? Pytam, gdyż jestem ciekaw czy tylko ja mam taki "problem", czy może większość ludzi uważa delegaty za twór przydatny tylko w niewielu sytuacjach?

To może ja zapytam - używasz LINQ?

Chyba nie powiesz mi że to:

int total = 0;
foreach (string line in lines)
{
    int len = line.Length;
    if (len > 8)
    {
        total += line.Length;
    }
}

Jest czytelniejsze/wygodniejsze w pisaniu od tego:

lines.Select(x => x.Length).Where(x => x > 8).Sum();

A w życiowych przykładach różnice w prostocie są zazwyczaj jeszcze większe...

I można przykłady mnożyć. Tak, używam delegatów.

0
msm napisał(a):

Jest czytelniejsze/wygodniejsze w pisaniu

Pierwszy kod to prosta, zrozumiała „dla każdego” pętla.
Drugi to jakaś magia, dziwne znaczki, składnia typowa dla tego akurat języka — wymaga więcej wiedzy, jest więc trudniejszy. I ma dużą szansę działać wolniej ;-)

od tego:

lines.Select(x => x.Length).Where(x => x > 8).Sum();

Ja myślę że w kontekście rozmowy o delegatach, właściwsze jest porównanie z tym:

        static int GetStringLength(string s)
        {
            return s.Length;
        }

        static bool IsGreaterThan8(int x)
        {
            return x > 8;
        }

        ...
            var lines2 = lines.Select<string,int>(GetStringLength).Where<int>(IsGreaterThan8).Sum();

Bo nie chodzi o LINQ vs nie-LINQ, tylko raczej: co dają lambdy i delegaty.

1
Azarien napisał(a):
msm napisał(a):

Jest czytelniejsze/wygodniejsze w pisaniu

Pierwszy kod to prosta, zrozumiała „dla każdego” pętla.
Drugi to jakaś magia, dziwne znaczki, składnia typowa dla tego akurat języka — wymaga więcej wiedzy, jest więc trudniejszy.
I ma dużą szansę działać wolniej ;-)

od tego:

lines.Select(x => x.Length).Where(x => x > 8).Sum();

Ja myślę że w kontekście rozmowy o delegatach, właściwsze jest porównanie z tym:

        static int GetStringLength(string s)
        {
            return s.Length;
        }

        static bool IsGreaterThan8(int x)
        {
            return x > 8;
        }

        ...
            var lines2 = lines.Select<string,int>(GetStringLength).Where<int>(IsGreaterThan8).Sum();

Bo nie chodzi o LINQ vs nie-LINQ, tylko raczej: co dają lambdy i delegaty.

Jeśli już chcesz koniecznie to rozpisywać, to raczej do tego:

Func<bool, int> IsGreaterThan8 = x=> x > 8; // delegat
Func<string, int> GetStringLength = s => s.Length; // delegat
var lines3 = lines.Select<string,int>(GetStringLength).Where<int>(IsGreaterThan8).Sum();

Nie ma znaczenia czy funkcje są zdefiniowane jako lambdy czy jako metody, tak czy inaczej technicznie używane są delegaty.

0
msm napisał(a):

Nie ma znaczenia czy funkcje są zdefiniowane jako lambdy czy jako metody, tak czy inaczej technicznie używane są delegaty.

Ty to wiesz, ja to wiem, ktoś kto nie widzi słowa kluczowego delegate może uznać to za brak delegatów.
Bo w ogóle, to wydaje mi się, że autorowi chodziło o to, czy sami jawnie definiujemy delegaty, a nie o użycie istniejących bądź niejawnych.

0

Delegaty i eventy są zajebiste.
Możesz sobie stworzyć klasę, która będzie wywoływać poszczególne eventy. Pod te eventy możesz podpiąć jakieś funkcji i dzięki temu możesz 'powiedzieć' klasie co ma robić w poszczególnych sytuacjach. Coś jak funkcje wirtualne, tylko że bez dziedziczenia.

0

Ty to wiesz, ja to wiem, ktoś kto nie widzi słowa kluczowego delegate może uznać to za brak delegatów.
Bo w ogóle, to wydaje mi się, że autorowi chodziło o to, czy sami jawnie definiujemy delegaty, a nie o użycie istniejących bądź niejawnych.

No właśnie, dokładnie o to mi chodziło.

Ja jakoś w życiowych swoich programach nie mogłem znaleźć sensownego zastosowania delegatów. Podane wyżej kody są jak dla mnie mało czytelne np to:

lines.Select(x => x.Length).Where(x => x > 8).Sum();

Zapisałbym tak:

int total = 0;
foreach (string line in lines)
{
    if (line.Length > 8)
        total += line.Length;
}

albo w ogóle crazy:

int total = 0;
foreach (string line in lines)
    if (line.Length > 8) total += line.Length;

I jak dla mnie jest to dużo bardziej czytelne, aczkolwiek mniej pr0 :) Jest to zapewne moja wina, gdyż nie mam obycia z LINQ zbyt dużego, ale... skoro można tak to po co sobie "udziwniać"?
No chyba, że ten "dziwny" kod np działa nieco szybciej itd.

Już o takich zapisach nie wspominam nawet:

Func<bool, int> IsGreaterThan8 = x=> x > 8; // delegat
Func<string, int> GetStringLength = s => s.Length; // delegat
var lines3 = lines.Select<string,int>(GetStringLength).Where<int>(IsGreaterThan8).Sum();

Na pierwszy rzut oka nic nie widzę tutaj i nie wiem co ten kod robi. Muszę się w niego zagłębić i czytać po 3 razy jedną linijkę. Nie o to chyba chodzi. Jednak tak jak mówię, nie jestem zbyt pr0 w C# i być może po prostu mam za mało obycia.

Delegaty i eventy w klasach to jedyna fajna rzeczy, która mi się w tym podoba. Może tutaj faktycznie popracuję i stworzę coś tylko dla zabawy, ale własnie za pomocą tych "technik"

Dziękuję wszystkim za odpowiedzi :)

1

Dla porównania, wspomniana funkcja w Scali:

lines.map(_.length).filter(_ > 3).sum

I w Haskellu:

sum.filter(>3).map length $ lines

Zresztą jak ktoś ma funkcyjne obycie to każda z tych postaci (Scala, Haskell czy LINQ) jest lepsza od topornej pętli.

0

LINQ tu jest zdecydowanie bardziej czytelny. No ale to jednak wymaga pewnej znajomości tego elementu .Net i języka.

3

Ale czemu linq nieczytelne? Wystarczy wiedzieć co oznaczają te "znaczki", jeśli ktoś to wie i rozumie to wtedy czytelne. Gdyby ktoś nie wiedział jak działa for, to pętla też by nie była czytelna.

0

Moglibyście polecić mi jakiś kurs bądź książkę na temat LINQ? Najlepiej jednak jakby była po polsku, aczkolwiek w krytycznych warunkach może być angielski. (po prostu boję się, że po angielsku pominę jakieś "istotne szczegóły" (specjalnie takie określenie)).

Z tego co szukałem to oczywiście znalazłem gotowe przykłady itd, ale coś od A do Z bym chciał. A jakoś ani kursów ani książek po polsku znaleźć nie potrafię. Może coś polecicie?

0

Nie wiem czy jest jakaś książka na ten temat, wydaje mi się, że to zbyt mały temat, żeby mu cała książkę poświęcić. Najlepszym źródłem takich informacji jest MSDN. Znalazłem właśnie całkiem fajny artykuł, w dodatku po polsku - http://msdn.microsoft.com/pl-pl/library/linq--csharp-3-0.aspx

0

Genialnie, bardzo dziękuję.

Ja od siebie dodam ten link co wspominałem wcześniej (z przykładami):
http://www.java2s.com/Code/CSharp/LINQ/CatalogLINQ.htm

0

ja korzystałem z tego:
http://helion.pl/ksiazki/c-3-0-i-net-3-5-technologia-linq-jacek-matulewski,cshtec.htm
oraz rozdziałów w większych pozycjach. teraz chyba nie ma dobrej książki "biblii" bez rozdziału o linqu...

1 użytkowników online, w tym zalogowanych: 0, gości: 1