我经常听到开发人员说C#功能非常强大。经常听到这个,我相信这是真的但是我没有经常使用功能,我仍然不明白他们的力量在哪里。我有两个问题:
1)C#函数的真正功能是什么,它们可以在哪里应用?
2)正常方法与函数不同,例如与下面两者的区别是什么:
public int GetNumberOfDays(int randomVariable);
和
Func<int,int>
答案 0 :(得分:3)
function<int, int>(); is not right
你的意思是:
Func<int,int>
它只是
的糖语法int delegate func(int a)
例如:
public void PrintMe(Func<int,int> f,string s)
{
}
答案 1 :(得分:1)
Func<int, int>
是一种委托类型,表示采用类型int
的一个参数并返回int
的方法。代表很强大:它们允许您将一个或多个函数传递给另一个函数。代表们也有其他权力,但我会在讨论中忽略它们。
将函数传递给另一个函数是Linq to Objects的一个关键概念:
int TimesTwo(int arg) { return arg * 2; }
int TimesThree(int arg) { return arg * 3; }
IEnumerable<int> DoubleTheSequence(IEnumerable<int> input)
{
return input.Select(TimesTwo);
}
IEnumerable<int> TripleTheSequence(IEnumerable<int> input)
{
return input.Select(TimesThree);
}
在这种情况下,我们使用Select
方法,该方法接受序列和函数,并返回将函数应用于输入序列的每个成员所产生的序列。
在上面的示例中,TimesTwo
和TimesThree
通过“隐式方法组转换”传递给Select方法。简而言之,编译器将裸方法名称转换为引用方法的正确重载的委托。术语是“method group ”,因为当方法重载时,名称将所有重载作为一组引用,编译器必须选择正确的重载。
编写几个方法可能不方便,因为我们想将它们传递给其他方法。这就是为什么C#引入匿名委托以及后来更简洁的 lambda表达式的原因。现在,假设我们希望能够使我们的序列翻两番,除了加倍或三倍。我们可以使用lambda:
,而不是编写一个名为TimesFour
的新函数
IEnumerable<int> QuadrupleTheSequence(IEnumerable<int> input)
{
return input.Select(i => i * 4);
}
最后,我们可以制作更通用的TransformTheSequenceInSomeArbitraryManner
方法:
IEnumerable<int> TransformTheSequenceInSomeArbitraryManner(IEnumerable<int> input, Func<int, int> f)
{
return input.Select(f);
}
该示例显然只是Select
方法的一个简单包装器,但它用于说明如何声明采用Func<int, int>
参数的方法。此方法显示使用该参数的两种方式:
int CallTheFunctionTwice(int input, Func<int, int> f)
{
int intermediateValue = f.Invoke(input);
int result = f(intermediateValue);
return result;
}
具体来说,您可以通过显式调用其Invoke
方法或使用方法调用语法来调用委托。两种方法的编译代码都是相同的。
最后,回答你的问题:
public int GetNumberOfDays(int randomVariable)
和Func<int,int>
之间的区别是什么?
第一个是方法声明;它声明了一个特定的方法,该方法接受int
参数并返回一个特定的int
,其值可能取决于参数的值。第二种是委托类型,它可以保存对具有相同签名的任何方法的引用。