C# 在F中创建本地函数#

C# 在F中创建本地函数#,c#,.net,f#,functional-programming,C#,.net,F#,Functional Programming,例如,我有两个加法函数: module Add let add2 a = let innerFn a = a + 2 innerFn a let add2' a = let innerFn' () = a + 2 innerFn' () let res1 = add2 0 let res2 = add2' 1 据我所知,innerFns将分别编译为FSharpFunc和FSharpFunc,并将在每次调用add2或add2'时初始化 如何重写代码以将它们转换

例如,我有两个加法函数:

module Add

let add2 a =
    let innerFn a = a + 2
    innerFn a
let add2' a =
    let innerFn' () = a + 2
    innerFn' ()

let res1 = add2 0
let res2 = add2' 1
据我所知,
innerFn
s将分别编译为
FSharpFunc
FSharpFunc
,并将在每次调用
add2
add2'
时初始化


如何重写代码以将它们转换为静态类的静态局部函数(因此没有FSharpFunc初始化),就像在C#7中一样?

您可能不必担心这一点。在调试构建中,每个本地函数都成为委托。在发布版本中,函数要么是内联的,要么成为静态类中的静态方法

通过在调试版本中构建和反编译问题代码,您可以获得:

public static int add2(int a)
{
    return 5 + (new Program.innerFn@5()).Invoke(a);
}

public static int add2'(int a)
{
    return (new Program.innerFn'@8(a)).Invoke(null);
}
每次都会显示一个委托初始化

但在发行版中,这将变成:

public static int add2(int a)
{
    return a + 2;
}

public static int add2'(int a)
{
    return a + 2;
}
函数是内联的,没有生成委托

为了避免内联,我将
add2
做得更复杂一些:

let add2 a =
    let innerFn a = if a < 3 then a+1 else a + 2
    5 + innerFn a
let add2' a =
    let innerFn' () = a + 2
    innerFn' () 
让我们添加2 a=
设innerFn a=如果a<3,则a+1,否则a+2
5+fn a
让我们加上2'a=
设innerFn’()=a+2
innerFn'()
在这种情况下,发布版本在类中生成了一个静态方法:

public static int add2(int a)
{
    return 5 + Program.innerFn@5(a);
}

public static int add2'(int a)
{
    return a + 2;
}

internal static int innerFn@5(int a)
{
    if (a < 3)
    {
        return a + 1;
    }
    return a + 2;
}
publicstaticintadd2(inta)
{
返回5+程序。innerFn@5(a) );
}
公共静态int add2'(int a)
{
返回a+2;
}
内部静态整数innerFn@5(INTA)
{
if(a<3)
{
返回a+1;
}
返回a+2;
}

您说内部函数成为您不想要的委托,可能是由于额外的分配。嗯,我不知道,而且也没那么好。C#7局部方法在语言级别的重要一点是它们是局部方法,而不是Func或Action委托。优化是一个(非常重要,非常受欢迎的)奖励。你真的那么关心委托分配吗?我认为在这种情况下,委托的生成只针对调试构建。发布版本将内部函数内联在一起,不会导致分配或调用