参数类型“无效”是不能分配给参数类型“System.Action”

问题描述:

这是我的测试代码:参数类型“无效”是不能分配给参数类型“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

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. 待办事项预计其不带参数的Action(即方法,无返回值)。因此WriteToConsoleWithSomethingExtra不是一个有效的适合 - 需要一个字符串参数。
    2. DO2接受一个Action<T>(即方法,该方法需要在一个T参数和没有返回值)。因此,当你调用委托/行动时,你需要提供一个T型参数,这里是String。

    在你的代码

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

    这样解释以下

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

    由于WriteToConsoleWithSomethingExtra的返回类型(“测试”)是无效的,所以你不能真正把它传递给dsufac.Do()。这就是为什么它没有被编译。但对于第一个

    dsufac.Do(WriteToConsole); 
    

    你是不是调用该函数,而你是把它当作一个方法组,这就是后来获得dsufac对象的DO()方法调用。但是如果你想写第三行作为第一行,你可以使用

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

    我在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 
    }