Func < string,string > 和 committee 之间的区别是什么?

我看到两种形式的代表:

A. Func<string, string> convertMethod = lambda


B. public delegate string convertMethod(string value);

我不确定这两者之间到底有什么区别。他们都是代表吗?我相信第一个将使用 lambda,第二个将必须有一个方法来实际执行工作。我可能也很困惑。

30927 次浏览

From MSDN,

In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous methods as the preferred way to write inline code.

and

There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures.

You may also be interested in this SO answer on delegate keyword vs lambda expression.

Additionally, MSDN has a 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
}

In the previous example, notice that the delegate signature has one implicitly-typed input parameter of type int, and returns an int. The lambda expression can be converted to a delegate of that type because it also has one input parameter (x) and a return value that the compiler can implicitly convert to type int. (Type inference is discussed in more detail in the following sections.) When the delegate is invoked by using an input parameter of 5, it returns a result of 25.

First of all, your two examples are doing two totally separate things. The first is declaring a generic delegate variable and assigning a value to it, the second is just defining a delegate type. Your example, more completely, would be:

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

But more to the point, both Func<string,string> and delegate string convertMethod(string) would be capable of holding the same method definitions whether they be methods, anonymous methods, or lambda expressions.

As for which you should use, depends on the situation. If you want your delegate to be defined more by what it takes and returns, then the generic delegates are perfect. If you want the delegate to have some special name that gives more definition of what that delegate should do (beyond simple Action, Predicate, etc) then creating your own delegate is always an option.

A initializes an instance of a delegate (that can be called immediately). It's a variable of type Func< string, string >.

B specifies the definition of a delegate (its signature). It can be used to later define variables of type convertMethod.

The code sample you have is confusing things a bit so let me try and clear it up. The following 2 items are delegate declarations. These are easy to spot because they will always contain the delegate keyword

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

This line of code is assigning a value to a local which is typed to a delegate

Func<string, string> local = lambda;

The above code is not limited to using just lambdas though. The value could also be a compatible method group or another delegate value.

One other item to note is that even though Func<string, string> and convertMethod are both delegates with identical signatures their values are not convertible to each other. For example the following is illegal

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