2011-10-02 66 views
2

委託的使用遵循與調用方法相同的規則 - 如果您允許顯式調用該方法,則只能通過委託來引用方法,這意味着您無法從靜態方法引用非靜態方法,即使你實際上沒有調用它。有沒有辦法解決這個問題?您可以在靜態上下文中引用非靜態方法嗎?

下面是一些用於執行保齡球卡塔的代碼,我的理想代碼行顯示在評論中。我被迫要經過靜態調用(和匿名的靜態方法的聲明),以使框架類代碼聲明符合我的心意:

public int FrameScore() 
    { 
     return scorer[FrameType()](this); 
     // I would like it to be 
     // return this.scorer[FrameType()](); 
    } 

    static Dictionary<LinkedFrame.FrameTypeEnum, Func<LinkedFrame, int>> scorer = 
     new Dictionary<LinkedFrame.FrameTypeEnum, Func<LinkedFrame, int>>() 
     { 
      {LinkedFrame.FrameTypeEnum.Strike, frame => frame.StrikeScore()}, 
      {LinkedFrame.FrameTypeEnum.Spare, frame => frame.SpareScore()}, 
      {LinkedFrame.FrameTypeEnum.Regular, frame => frame.RegularScore()} 
      // I would like an element to be 
      // {LinkedFrame.FrameTypeEnum.Strike, StrikeScore} 
     }; 

    private int RegularScore() 
    { 
     return this.Sum; 
    } 

    private int SpareScore() 
    { 
     ... 
    } 

    private int StrikeScore() 
    { 
     ... 
    } 

因此,在某些情況下這將是有意義的推理在非靜態方法一個靜態上下文。有沒有辦法做到這一點?

+1

你在你的FrameScore方法中考慮過一個簡單的'switch'語句嗎? – dtb

+1

你*可以*從靜態上下文中引用非靜態方法,你不能做的就是引用'this'上的方法,因爲沒有'this'。你可以通過明確地傳遞一個類似這個參數來解決這個問題,但是你也可以使得這個方法是非靜態的。 – harold

+0

在構造函數中初始化(非靜態)字典將工作。當然非常低效。你需要的是相當於C++中的成員函數指針。在C++/CLI中支持爲「未綁定代理」,而不是在C#中。 –

回答

4

也許公開的實例代表會有幫助嗎?

根據MSDN: Delegate Class

當委託表示一個實例方法閉合在其第一個參數(最常見的情況),則代表存儲到方法入口點的參考和參考到一個對象,稱爲目標,它是可分配給定義該方法的類型的類型。當委託表示一個打開的實例方法時,它存儲對方法入口點的引用。代表簽名必須在其形式參數列表中包含隱藏該參數;在這種情況下,委託沒有對目標對象的引用,並且在調用委託時必須提供目標對象。

什麼它歸結爲是,你可以一個實例方法悄悄轉換爲靜態方法有一個明確的this參數。你可以看到它是如何完成的:Simon Cooper: Introduction to open instance delegates

3

實例方法總是需要調用一個實例。

如果要調用通過委託的實例方法,你有兩個選擇:

  1. 委託捕捉以某種方式實例。
  2. 您需要將實例傳遞給委託。

您似乎想擁有一個不捕獲實例並且不需要實例傳遞的委託。這在C#中是不可能的。

相關問題