2010-08-02 112 views
15

這是我的測試代碼:參數類型「無效」是不能分配給參數類型「System.Action」

class PassingInActionStatement 
{ 
    static void Main(string[] args) 
    { 
     var dsufac = new DoSomethingUsefulForAChange(); 

     dsufac.Do(WriteToConsole); 
     dsufac.Do2(s => WriteToConsoleWithSomethingExtra("Test")); 
     dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); // Does not compile 
    } 

    internal static void WriteToConsole() 
    { 
     Console.WriteLine("Done"); 
    } 

    internal static void WriteToConsoleWithSomethingExtra(String input) 
    { 
     Console.WriteLine(input); 
    } 
} 

internal class DoSomethingUsefulForAChange 
{ 
    internal void Do(Action action) 
    { 
     action(); 
    } 

    internal void Do2(Action<String> action) 
    { 
     action(""); 
    } 
} 

第2個呼叫工作,但我很奇怪,爲什麼第三一個沒有。我不喜歡Do2內部的代碼,因爲看起來很奇怪,我在那裏輸入了類型action("")以便使其工作。

可能有人請解釋兩件事情我不明白嗎?

  1. 爲什麼,爲什麼我必須寫操作(「」),以便讓它在DO2
+0

我始終標記的答覆,幫助我。如果沒有提供有用的解決方案,我不標記它,直到我得到幫助我的答案。 – 2010-08-02 12:43:43

回答

32
dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); 

實際工作,我不能調用待辦事項

  • 寫第三行一樣,首先調用函數(WriteToConsoleWithSomethingExtra("Test")),然後嘗試將結果傳遞到Do。由於沒有結果(void),所以不可能。

    你真正想要的是這樣的:

    dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test")); 
    

    內部件聲明一個函數,也不做(() =>位),執行時調用WriteToConsoleWithSomethingExtra("Test")然後你的dsufac.Do電話會收到一個動作,就像它期望的那樣。

    至於Do2 - 你已經宣佈它爲採取Action<String>,這意味着action是一個函數,有一個參數。你必須傳遞一個字符串。該字符串可以在你action("")例子是空的,像,也可能在外部的東西通過,像這樣:

    dsufac.Do3(WriteToConsole, "Test"); 
    
    ... 
    
    internal void Do3(Action<String> action, String str) 
    { 
        action(str); 
    } 
    
  • +0

    Waw!這樣可行。我仍然有很多問題與該行動和功能的東西。除了MSDN或您可以建議的書以外,是否還有一些體面的教程?當它允許我(顯然必須等待另一分鐘)時,我會標記你的答案。 – 2010-08-02 12:48:41

    +0

    感謝您的額外更新。 – 2010-08-02 12:54:11

    1
    1. 待辦事項預計其不帶參數的Action(即方法,無返回值)。因此WriteToConsoleWithSomethingExtra不是一個有效的適合 - 需要一個字符串參數。
    2. DO2接受一個Action<T>(即方法,該方法需要在一個T參數和沒有返回值)。因此,當你調用委託/行動時,你需要提供一個T型參數,這裏是String。
    3

    在你的代碼

    dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); 
    

    這樣解釋以下

    var variable = WriteToConsoleWithSomethingExtra("Test"); 
    dsufac.Do(variable); 
    

    由於WriteToConsoleWithSomethingExtra的返回類型(「測試」)是無效的,所以你不能真正把它傳遞給dsufac.Do()。這就是爲什麼它沒有被編譯。但對於第一個

    dsufac.Do(WriteToConsole); 
    

    你是不是調用該函數,而你是把它當作一個方法組,這就是後來獲得dsufac對象的DO()方法調用。但是如果你想寫第三行作爲第一行,你可以使用

    dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test")); 
    
    1

    我在Silverlight應用程序中做了這樣的一段時間。現在,它運行時,它的一部分會中斷。
    這發生在一個Silverlight子窗口:

    (my object context).SaveChanges(() => ChangesSaved()); 
    
    private void ChagngesSaved() 
    { 
        DialogResult = true: // is supposed to close the child window. line gets hit, does not close 
    } 
    
    相關問題