gpt4 book ai didi

C# 和 F# lambda 表达式代码生成

转载 作者:IT王子 更新时间:2023-10-29 04:22:16 29 4
gpt4 key购买 nike

让我们看一下由 F# 为简单函数生成的代码:

let map_add valueToAdd xs =
xs |> Seq.map (fun x -> x + valueToAdd)

lambda 表达式(F# 函数值实例)的生成代码如下所示:

[Serializable]
internal class map_add@3 : FSharpFunc<int, int> {
public int valueToAdd;
internal map_add@3(int valueToAdd) { this.valueToAdd = valueToAdd; }
public override int Invoke(int x) { return (x + this.valueToAdd); }
}

并查看几乎相同的 C# 代码:

using System.Collections.Generic;
using System.Linq;

static class Program {
static IEnumerable<int> SelectAdd(IEnumerable<int> source, int valueToAdd) {
return source.Select(x => x + valueToAdd);
}
}

以及为 C# lambda 表达式生成的代码:

[CompilerGenerated]
private sealed class <>c__DisplayClass1 {
public int valueToAdd;
public int <SelectAdd>b__0(int x) { return (x + this.valueToAdd); }
}

所以我有一些问题:

  • 为什么 F# 生成的类未标记为密封
  • 为什么 F# 生成的类包含 public 字段,因为 F# 不允许可变闭包?
  • 为什么 F# 生成的类有一个构造函数?它可以用公共(public)字段完美初始化...
  • 为什么 C# 生成的类没有标记为 [Serializable]?此外,为 F# 序列表达式生成的类也变成了 [Serializable],而为 C# 迭代器生成的类则没有。

最佳答案

由于它们是编译器生成的,密封/公共(public)字段问题有点没有实际意义——除非通过调试工具,否则你不应该看到它——你将如何子类化它或改变它,除非绕过编译器?如果您拥有那个级别的调试访问权限,您可以无论如何(通过反射)改变它。

对于 C# 它需要 top 是一个 field 以允许特定的 ref/out 用法,并允许正确使用捕获的可变结构 (是的,邪恶,我们知道)。我假设 F# 在这里是相似的(你能改变捕获值的子[子[子]]成员吗?)。不过,成员可能是内部成员。

重新 [Serialziable];为什么支持闭包的东西是可序列化的?代表是极差的连载候选人。也许 F# 的性质意味着它更适合将操作(流中)持久化到磁盘——但总的来说,我不会推荐它。我不希望这些对象(迭代器和捕获类)是可序列化的。

关于C# 和 F# lambda 表达式代码生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2948592/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com