2011-07-25 11 views
43

widzę delegatów w dwóch formach:Jaka jest różnica między Func <string, string> i delegate?

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value); 

jestem niepewny co rzeczywiście różnica między tymi dwoma są. Czy obaj są delegatami? Sądzę, że pierwszy użyłby lambda, a drugi musiałby mieć metodę, by faktycznie wykonać pracę. Też mogę być zdezorientowany.

+0

możliwe duplikat [stwierdzenie pełnomocnik ręcznie lub używać funkc Działanie ?] (Http://stackoverflow.com/questions/4482613/declare-delegate-manually-use-funct -lub-actiont) – nawfal

Odpowiedz

39

Przede wszystkim, dwa przykłady robią dwie całkowicie odrębne rzeczy. Pierwszym jest deklarowanie ogólnej zmiennej delegującej i przypisywanie jej wartości, a drugim jest właśnie określenie typu delegate. Twój przykład, pełniej, byłoby:

public static class Program 
{ 
    // you can define your own delegate for a nice meaningful name, but the 
    // generic delegates (Func, Action, Predicate) are all defined already 
    public delegate string ConvertedMethod(string value); 

    public static void Main() 
    { 
     // both work fine for taking methods, lambdas, etc. 
     Func<string, string> convertedMethod = s => s + ", Hello!"; 
     ConvertedMethod convertedMethod2 = s => s + ", Hello!"; 
    } 
} 

Ale bardziej na miejscu, zarówno Func<string,string> i delegate string convertMethod(string) byłby w stanie utrzymać te same definicje metod czy są sposoby, metody anonimowe, lub wyrażenia lambda.

Do czego należy użyć, zależy od sytuacji. Jeśli chcesz, aby Twój delegat był bardziej zdefiniowany przez to, co przyjmuje i wraca, to generyczni delegaci są doskonali. Jeśli chcesz, aby delegat miał jakąś specjalną nazwę, która daje więcej definicji tego, co delegat powinien zrobić (poza prostymi Action, Predicate, itp.), Tworzenie własnych delegatów jest zawsze opcją.

8

Od MSDN,

W wersjach C# przed 2.0, jedynym sposobem, aby zadeklarować delegat był używać nazwanych metod. W C# 2.0 wprowadzono metody anonimowe, aw C# w wersji 3.0 i nowszych wyrażenia lambda zastępują metody anonimowe jako preferowany sposób zapisywania kodu wbudowanego ( ).

i

Jest jeden przypadek, w którym sposób anonimowy zapewnia funkcjonalność nie znaleziono w wyrażeniach lambda. Anonimowe metody pozwalają pominąć listę parametrów. Oznacza to, że anonimową metodę można przekształcić w delegatów z różnymi podpisami.

Możesz być także zainteresowany tą odpowiedzią w języku angielskim na delegate keyword vs lambda expression.

Dodatkowo MSDN ma good article on Lambda Expressions:

delegate int del(int i); 
static void Main(string[] args) 
{ 
    del myDelegate = x => x * x; 
    int j = myDelegate(5); //j = 25 
} 

W poprzednim przykładzie, zauważyć, że podpis delegat ma jeden niejawnie wpisany parametr wejściowy typu int i zwraca int. Wyrażenie lambda można przekonwertować na delegata tego typu, ponieważ ma również jeden parametr wejściowy (x) i wartość zwracaną, którą kompilator może niejawnie przekonwertować na typ int. (Typ wnioskowanie jest omówione bardziej szczegółowo w kolejnych rozdziałach.) Gdy pełnomocnik jest wywoływana za pomocą parametru wejściowego 5, zwraca wynik 25.

+0

Można również pominąć parametry z lambda.() => Console.Writeline ("parametr mniej lambda") –

+0

Action test =() => Console.Writeline ("parametr less lambda"); test.Invoke(); –

2

Inicjuje wystąpienie delegata (można go natychmiast wywołać). Jest to zmienna typu Func < ciąg, ciąg>.

B określa definicję osoby pełnomocnej (jej podpis). Może być używany do późniejszego definiowania zmiennych typu convertMethod.

9

Próbka kodu jest nieco myląca, więc pozwól, że spróbuję ją wyczyścić. Poniższe 2 elementy są delegowanymi deklaracjami. Są łatwe do wykrycia, ponieważ zawsze będą zawierać delegate słowa kluczowego

public delegate TReturn Func<TArg, TReturn>(Targ value); 
public delegate string convertMethod(string value); 

Ta linia kodu jest przypisanie wartości do lokalnego, który jest wpisany do delegata

Func<string, string> local = lambda; 

Powyższy kod nie jest ograniczony do używania tylko lambdas. Wartością może być również kompatybilna grupa metod lub inna wartość delegata.

Jeden inny element, aby zauważyć, że chociaż Func<string, string> i convertMethod są zarówno delegaci z identycznych podpisów ich wartości są nie zamienny do siebie. Na przykład, po to nielegalne

Func<string, string> local1 = ...; 
convertMethod local2 = local1; // Error!!! 
Powiązane problemy