局部函数vs Lambda C#7.0
我正在查看中的新实现,我发现它们实现了本地函数很有趣,但我无法想象一个场景,其中本地函数比lambda表达式更受欢迎,这两者之间的区别是什么 我确实理解lambda是匿名的,而本地函数不是,但我无法理解一个真实的场景,其中本地函数比lambda表达式有优势 任何例子都将不胜感激。谢谢。: 您需要一个助手函数。您只能在单个函数中使用它,并且它可能使用包含该函数的范围内的变量和类型参数。另一方面,与lambda不同,您不需要将其作为第一类对象,因此不需要为其指定委托类型并分配实际的委托对象。此外,您可能希望它是递归的或泛型的,或者将其实现为迭代器 要进一步扩展,其优点是:局部函数vs Lambda C#7.0,c#,function,lambda,c#-7.0,C#,Function,Lambda,C# 7.0,我正在查看中的新实现,我发现它们实现了本地函数很有趣,但我无法想象一个场景,其中本地函数比lambda表达式更受欢迎,这两者之间的区别是什么 我确实理解lambda是匿名的,而本地函数不是,但我无法理解一个真实的场景,其中本地函数比lambda表达式有优势 任何例子都将不胜感激。谢谢。: 您需要一个助手函数。您只能在单个函数中使用它,并且它可能使用包含该函数的范围内的变量和类型参数。另一方面,与lambda不同,您不需要将其作为第一类对象,因此不需要为其指定委托类型并分配实际的委托对象。此外,您
ref
传递),这同样避免了分配
这也意味着调用本地函数更便宜,而且它们可以内联,可能会进一步提高性能null
赋值给委托变量,然后是lambda。局部函数自然可以是递归的(包括相互递归的)收益返回
(和收益中断
)关键字来实现IEnumerable
-返回功能。可以使用本地功能int add(int x, int y) => x + y;
Func<int, int, int> add = (x, y) => x + y;
intadd(intx,inty)=>x+y;
Func add=(x,y)=>x+y;
它们可以在函数中的任何位置定义,即使在
return
语句之后也是如此
public double DoMath(double a, double b)
{
var resultA = f(a);
var resultB = f(b);
return resultA + resultB;
double f(double x) => 5 * x + 3;
}
我使用内联函数来避免垃圾收集压力,特别是在处理长时间运行的方法时。假设一个人想要获得给定股票代码的两年或市场数据。此外,如果需要,可以打包许多功能和业务逻辑 我们要做的是打开一个到服务器的套接字连接,并在将事件绑定到事件的数据上循环。我们可以用设计类的同样方式来考虑它,只有一种方法不是到处编写帮助器方法,它们实际上只为一部分功能工作。下面是一些可能的示例,请注意,我使用的是变量,“helper”方法位于finally下面。在最后一个示例中,我很好地删除了事件处理程序,如果我的Exchange类是外部的/注入的,我就不会注册任何挂起的事件处理程序
void List<HistoricalData> RequestData(Ticker ticker, TimeSpan timeout)
{
var socket= new Exchange(ticker);
bool done=false;
socket.OnData += _onData;
socket.OnDone += _onDone;
var request= NextRequestNr();
var result = new List<HistoricalData>();
var start= DateTime.Now;
socket.RequestHistoricalData(requestId:request:days:1);
try
{
while(!done)
{ //stop when take to long….
if((DateTime.Now-start)>timeout)
break;
}
return result;
}finally
{
socket.OnData-=_onData;
socket.OnDone-= _onDone;
}
void _OnData(object sender, HistoricalData data)
{
_result.Add(data);
}
void _onDone(object sender, EndEventArgs args)
{
if(args.ReqId==request )
done=true;
}
}
void List RequestData(Ticker-Ticker,TimeSpan超时)
{
var套接字=新交易所(股票代码);
bool done=false;
socket.OnData+=\u OnData;
socket.OnDone+=\u OnDone;
var request=NextRequestNr();
var result=新列表();
var start=DateTime.Now;
socket.RequestHistoricalData(requestId:request:days:1);
尝试
{
而(!完成)
{//需要很长时间时停止…。
if((DateTime.Now start)>超时)
打破
}
返回结果;
}最后
{
socket.OnData-=\u OnData;
socket.OnDone-=\u OnDone;
}
void_OnData(对象发送方,历史数据)
{
_结果.添加(数据);
}
void _onDone(对象发送方、EndEventArgs参数)
{
if(args.ReqId==请求)
完成=正确;
}
}
您可以看到下面提到的优点,这里您可以看到一个示例实现。希望这有助于解释其好处 如果您还想知道如何测试本地功能,您应该检查一下,因为它具有测试本地功能。下面是一个将要测试的简单类示例:
public class Foo // the class under test
{
public int GetResult()
{
return 100 + GetLocal();
int GetLocal ()
{
return 42;
}
}
}
下面是测试结果:
[TestClass]
public class MockLocalFunctions
{
[TestMethod]
public void BasicUsage()
{
//Arrange
var foo = Mock.Create<Foo>(Behavior.CallOriginal);
Mock.Local.Function.Arrange<int>(foo, "GetResult", "GetLocal").DoNothing();
//Act
var result = foo. GetResult();
//Assert
Assert.AreEqual(100, result);
}
}
[TestClass]
公共类MockLocalFunctions
{
[测试方法]
公共空间基本概念()
{
//安排
var foo=Mock.Create(Behavior.CallOriginal);
Mock.Local.Function.Arrange(foo,“GetResult”,“GetLocal”).DoNothing();
//表演
var result=foo.GetResult();
//断言
断言.AreEqual(100,结果);
}
}
这里有一个到JustMock的链接
免责声明。我是负责.泛型、out参数、递归函数(无需将lambda初始化为null)等的开发人员之一。@KirkWoll-您应该将此作为答案发布。我想补充一点,本地函数在调用方有参数名。Lambdas没有。@Lensflare Lambdas的参数名确实没有保留,但这是因为它们必须转换为委托,委托有自己的名称。例如:
Func f=(x,y)=>x+y;f(arg1:1,arg2:1)代码>。很棒的列表!但是,我可以想象IL/JIT编译器如何执行1中提到的所有优化。如果