C#和F#lambda表达式代码生成 [英] C# and F# lambda expressions code generation

查看:100
本文介绍了C#和F#lambda表达式代码生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们看一下F#为简单功能生成的代码:

Let's look at the code, generated by F# for simple function:

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

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

The generated code for lambda expression (instance of F# functional value) will looks like this:

[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#代码:

And look at nearly the same C# code:

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表达式生成的代码:

And the generated code for the C# lambda expression:

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

所以我有一些问题:

  • 为什么F#生成的类未标记为sealed?
  • 由于F#不允许可变闭包,为什么F#生成的类包含 public 字段?
  • 为什么F#生成的类具有构造函数?可以使用公共字段完美地初始化它.
  • 为什么C#生成的类未标记为[Serializable]?同样,为F#序列表达式生成的类也变为[Serializable],而为C#迭代器生成的类却没有.
  • Why is F#-generated class not marked as sealed?
  • Why does F#-generated class contain public fields since F# doesn't allow mutable closures?
  • Why does F# generated class have a constructor? It may be perfectly initialized with the public fields...
  • Why is C#-generated class not marked as [Serializable]? Also classes generated for F# sequence expressions also became [Serializable] and classes for C# iterators do not.

推荐答案

由于它们是由编译器生成的,因此,密封的/公共领域的问题有些争议-除了调试工具之外,您永远都不会看到它-您将如何是子类化还是变异它,除非一步步走遍编译器?如果您具有那个级别的调试访问权限,则可以 对其进行更改(通过反射).

Since they are compiler-generated, the sealed / public field issues are a bit moot - you shouldn't ever see it except via debug tools - how would you be subclassing it or mutating it, except by stepping around the compiler? If you have that level of debug access you can mutate it anyway (via reflection).

对于C#,它首先需要是一个 field ,以允许某些ref/out使用,并允许正确使用捕获的可变结构(是的,邪恶的,我们知道).我假设这里的F#是类似的(您可以对捕获值的sub- [sub- [sub-]]成员进行突变吗?).但是,这些成员可能是内部成员.

For C# it needs top be a field to allow certain ref / out usage, and to allow correct usage with captured mutable structs (yes, evil, we know). I assume F# is similar here (can you mutate a sub-[sub-[sub-]]member of the captured value?). The members could probably be internal, though.

Re [Serialziable];为什么支撑闭包的东西可以序列化?代表们成为极差的序列化候选者.也许F#的性质意味着它更适合于将操作(中间流)持久化到磁盘上-但是总的来说,我不建议这样做.我不希望这些对象(迭代器和捕获类)可序列化.

Re [Serialziable]; why would something that underpins a closure be serializable? Delegates make extremely poor serialization candidates. Maybe the nature of F# means that it is better suited to persisting an operation (mid-flow) to disk - but in general, I wouldn't recommend it. I would have no expectation of these objects (iterators and capture-classes) being serialzable.

这篇关于C#和F#lambda表达式代码生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆