亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將匿名 lambda 轉換為強類型委托會禁用編譯器緩存嗎?

將匿名 lambda 轉換為強類型委托會禁用編譯器緩存嗎?

C#
心有法竹 2022-11-13 17:32:50
我試圖了解編譯器支持的委托緩存的邊緣情況以避免內存分配。例如,據我了解,此委托被緩存到單個實例并被重用,因為它不會關閉任何局部變量:int[] set = new [] { 1, 2, 3, 4, 5, 6 }; var subset = set.Where(x => x % 2 == 0);現在,在某些情況下,我生成的代碼可能想直接調用委托,因此匿名方法在 C# 中無效,如下所示:var result = (x => x % 2 == 0).Invoke(5); // Invalid為了避免這種情況,我看到了兩種選擇:使用構造函數:var result = (new Func<int, bool>(x => x % 2 == 0)).Invoke(5);鑄造匿名委托:var result = ((Func<int, bool>)(x => x % 2 == 0)).Invoke(5);我假設編譯器不會在選項 #1 中緩存委托,但我不確定它是否會在 #2 中緩存。這在任何地方都有記錄嗎?
查看完整描述

1 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

我假設編譯器不會在選項 #1 中緩存委托,但我不確定它是否會在 #2 中緩存。

事實上,在這兩種情況下都可以,而且它們是捆綁在一起的。

來自 ECMA C# 5 規范,第 7.6.10.5 節:

new D(E) 形式的委托創建表達式(其中 D 是委托類型,E 是表達式)的綁定時處理包括以下步驟:

  • ...

  • 如果 E 是匿名函數,則委托創建表達式的處理方式與從 E 到 D 的匿名函數轉換(第 6.5 節)相同。

  • ...

所以基本上兩者的處理方式相同。在這兩種情況下,它都可以被緩存。是的,“新并不一定意味著新”是很奇怪的。

為了說明這一點,讓我們編寫一個非常簡單的程序:

using System;


public class Program

{

    public static void Main()

    {

        var func = new Func<int, bool>(x => x % 2 == 0);

    }

}

這是我機器上的方法的 IL Main(誠然是使用 C# 8 預覽版編譯器構建的,但我希望在一段時間內也是如此):


.method public hidebysig static void  Main() cil managed

{

  .entrypoint

  // Code size       29 (0x1d)

  .maxstack  8

  IL_0000:  ldsfld     class [mscorlib]System.Func`2<int32,bool> Program/'<>c'::'<>9__0_0'

  IL_0005:  brtrue.s   IL_001c

  IL_0007:  ldsfld     class Program/'<>c' Program/'<>c'::'<>9'

  IL_000c:  ldftn      instance bool Program/'<>c'::'<Main>b__0_0'(int32)

  IL_0012:  newobj     instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,

                                                                                      native int)

  IL_0017:  stsfld     class [mscorlib]System.Func`2<int32,bool> Program/'<>c'::'<>9__0_0'

  IL_001c:  ret

} // end of method Program::Main

這是有效的:


Func<int, bool> func;

func = cache;

if (func == null)

{

    func = new Func<int, bool>(GeneratedPrivateMethod);

    cache = func;

}


查看完整回答
反對 回復 2022-11-13
  • 1 回答
  • 0 關注
  • 114 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號