2011-07-25 24 views
43

veo delegados en dos formas:¿Cuál es la diferencia entre Func <string, string> y delegate?

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value); 

estoy seguro de lo que en realidad la diferencia entre estos dos son. ¿Son ambos delegados? Creo que el primero usaría una lambda y el segundo tendría que tener un método para realizar el trabajo. También puedo estar confundido.

+0

posible duplicado de [Declarar delegado manualmente, utilice Func o Acción ?] (Http://stackoverflow.com/questions/4482613/declare-delegate-manually-use-funct -or-actiont) – nawfal

Respuesta

39

En primer lugar, sus dos ejemplos están haciendo dos cosas totalmente separadas. El primero es declarar una variable de delegado genérica y asignarle un valor, el segundo es simplemente definir un tipo delegate. Su ejemplo, más completo, sería:

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!"; 
    } 
} 

embargo, más al punto, tanto Func<string,string> y delegate string convertMethod(string) sería capaz de mantener las mismas definiciones de métodos ya sean métodos, métodos anónimos, o expresiones lambda.

En cuanto a lo que debe utilizar, depende de la situación. Si desea que su delegado se defina más por lo que toma y lo que vuelve, entonces los delegados genéricos son perfectos. Si desea que el delegado tenga algún nombre especial que brinde más definición de lo que debe hacer ese delegado (más allá del simple Action, Predicate, etc.) entonces crear su propio delegado siempre es una opción.

8

De MSDN,

En las versiones de C# 2.0 antes, la única manera de declarar un delegado fue utilizar métodos llamados. C# 2.0 introdujo métodos anónimos y en C# 3.0 y versiones posteriores, las expresiones lambda reemplazan a los métodos anónimos como la forma preferida de escribir código en línea.

y

hay un caso en el que un método anónimo proporciona funcionalidad no se encuentra en las expresiones lambda. Los métodos anónimos le permiten omitir la lista de parámetros. Esto significa que un método anónimo puede ser convertido a delegados con una variedad de firmas.

Quizás te interese esta respuesta SO en delegate keyword vs lambda expression.

Además, MSDN tiene una 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 
} 

En el ejemplo anterior, observe que la firma del delegado tiene un parámetro de entrada escrito implícita de tipo int, y devuelve un int. La expresión lambda se puede convertir a un delegado de ese tipo porque también tiene un parámetro de entrada (x) y un valor de retorno que el compilador puede convertir implícitamente a tipo int. (Tipo inferencia se discute en más detalle en las secciones siguientes). Cuando el delegado se invoca mediante el uso de un parámetro de entrada de 5, devuelve un resultado de 25.

+0

También puede omitir parámetros de lambda.() => Console.Writeline ("parámetro menos lambda") –

+0

Prueba de acción =() => Console.Writeline ("parámetro menos lambda"); test.Invoke(); –

2

A inicializa una instancia de un delegado (que se puede llamar de inmediato). Es una variable de tipo Func < string, string>.

B especifica la definición de un delegado (su firma). Se puede usar para definir posteriormente las variables del tipo convertMethod.

9

La muestra de código que tiene es un poco confusa, así que déjeme intentar y aclararla. Los siguientes 2 elementos son declaraciones delegadas. Estos son fáciles de detectar, ya que siempre contienen la palabra clave delegate

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

Esta línea de código es la asignación de un valor a un local que se escribe a un delegado

Func<string, string> local = lambda; 

El código anterior no se limita a usar solo lambdas sin embargo. El valor también podría ser un grupo de métodos compatible u otro valor de delegado.

Otro elemento a tener en cuenta es que a pesar de Func<string, string> y convertMethod son los dos delegados con firmas idénticas sus valores son no convertibles entre sí. Por ejemplo, la siguiente es ilegal

Func<string, string> local1 = ...; 
convertMethod local2 = local1; // Error!!! 
Cuestiones relacionadas