2011-09-20 56 views
4

這編譯但第二個方法被標記爲「函數在所有路徑上遞歸」。並調用它會導致StackOverflowException。 Intellisense(w/ReSharper)提供了作爲屬性的Invoke。Func <T>上的Invoke屬性是什麼?

public class Class1 
{ 
    public void MyMethod(string value) 
    { 
     Console.WriteLine(value); 
    } 

    public void MyMethod(Func<string> getValue) 
    { 
     MyMethod(getValue.Invoke); 
    } 
} 

將其更改爲這個工程按預期:

public void MyMethod(Func<string> getValue) 
    { 
     MyMethod(getValue.Invoke()); 
    } 

這是怎麼回事?這只是Intellisense的怪異還是實際上有一個Invoke屬性?

回答

9

這是Invoke方法 - 但通過方法組轉換轉換...然後遞歸。看看這使得它更清楚 - 它的等效代碼:

public void MyMethod(Func<string> getValue) 
{ 
    Func<string> func = getValue.Invoke; 
    MyMethod(func); // Eek, recursive! 
} 

(我會承擔你所熟悉的方法組轉換爲獲取委託實例的一個方式的那一刻讓我知道。你不是和我將進入更多的細節)

+0

我很熟悉方法組轉換,只是意味着在將事件添加到事件時不再需要新建事件處理程序委託。那是我唯一明白地遇到它的時候。 Intellisense不提示方法簽名令人失望。 –

+0

@Jamie:好吧,它不是隻填寫名字,正如它通常那樣?這取決於你使它成爲方法調用。 –

+0

ReSharper自動添加方法調用,所以我想我不應該在Intellisense上過於努力。但它很混亂,因爲通常你不能擁有一個方法和一個簽名相同的屬性。 –

-2

要添加到Jon的回答,請注意,原因你不能找到對象瀏覽器的Invoke成員是因爲,每the docs

備註

公共語言運行庫爲每個 委託類型提供了一個Invoke方法,具有與委託相同的簽名。因爲編譯器會自動調用它,所以您不需要從C#,Visual Basic或Visual C++中明確調用此方法。 Invoke方法是 當您想要查找委託類型的簽名時反射很有用。

+0

這個答案對我來說沒有意義。 「Invoke」方法通過Intellisense和對象瀏覽器在每個代理中完美可見。 – mquander

+0

@mquander如果能夠在對象瀏覽器中的委託類型上提供「Invoke」的屏幕截圖,將會非常棒,我似乎無法在我的程序中找到它。 – AakashM

+0

下面是一個:http://imgur.com/Ygczo – mquander