繁体   English   中英

C#中的委托与F#中的第一类值有什么区别?

[英]What is the difference between delegates in C# and functions as first class values in F#?

更具体地说,代表具有作为F#中的第一类值的函数的特征(如果有的话)没有; 作为第一类值的特征有什么特征(如果有的话)在C#中委托没有?

代表和F#“一流的功能价值”是完全不同的。

委托是CLR的一种机制,它是一个围绕函数指针+对象对的类型安全包装器(例如方法, this -pointer与方法地址一起被捕获)。

另一方面,F#函数值是抽象类FSharpFunc<,> (它曾经在F#正式发布之前被称为FastFunc<,> )。 调用通过普通的虚方法发生,这比委托调用快得多。 这就是F#-team首先不使用委托的原因。

因此,如果您可以通过抽象类/虚方法“实现”作为第一类值的函数,为什么Microsoft会添加委托?

  • 没有其他选择在.NET 1.0 / 1.1中,没有泛型,因此您必须为要使用的每个函数签名定义新的委托类型(=“函数类型”)。
  • (不,只是使用Java中的接口不计算。:-P)

好的,但是从.NET 2.0开始我们有Generics,为什么我们还有代表呢? 为什么我们不能只使用Func<,>Action<>来做所有事情?

  • 向后兼容性
  • 多播代理可以将代理链接在一起以形成新的代理。 此机制用于在VB.NET和C#中实现事件。 在幕后,一个事件实际上只是一个代表字段。 使用+=语法,您实际上将事件处理程序委托添加到事件字段中的委托链。

除了事件,是否有理由使用委托而不是FSharpFunc<,>

是的,一: FSharpFunc<,>每个实现,包括lambda-expressions *,都是一个新类。 在.NET中,类编译在已编译程序集的元数据中。 另一方面,代表不需要额外的元数据。 委托类型可以,但实例化这些委托类型在元数据方面是免费的。

但是等等,C#lambda-expressions /匿名方法是不是实现为隐藏类?

是的,C#lambdas占据了两个世界中最糟糕的^^

我只是想补充说SealedSun的这句话不是真的:

调用通过普通的虚方法发生,这比委托调用快得多。 这就是F#-team首先不使用委托的原因。

F#函数并不比委托调用快,可能是.NET 1.0中的情况,但现在委托调用和调用虚拟方法几乎相当。

与调用委托相比,调用编译器静态绑定的F#函数也非常慢。

open System
open System.Diagnostics

let time name f = 
  let sw = new Stopwatch()
  sw.Start()
  f()
  sw.Stop()
  printfn "%s: %dms" name sw.ElapsedMilliseconds

time "delegate call" (
  fun () ->
    let f = 
      new Func<int, int, int>(
        fun i1 i2 -> 
          let y = i1 + i2
          let x = y + i1
          let z = x + y + i2
          z + x + y + i1
      )

    let mutable r = 0
    for i = 0 to 10000000 do
      r <- f.Invoke(i, i)
)

let f i1 i2 = 
  let y = i1 + i2
  let x = y + i1
  let z = x + y + i2
  z + x + y + i1

time "fsharp func (static bound)" (
  fun () ->
    let mutable r = 0
    for i = 0 to 10000000 do
      r <- f i i
)

let make f =
  let mutable r = 0
  for i = 0 to 10000000 do
    r <- f i i

time "fsharp func (dynamic bound)" (
  fun () -> make f
)

Console.ReadLine() |> ignore

在我的计算机上生成以下结果

delegate call: 65ms
fsharp func (staticly linked): 4ms
fsharp func (dynamic invoke): 356ms

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM