【问题标题】:C# delegate only writes out last methodC#委托只写出最后一个方法
【发布时间】:2017-09-22 10:56:45
【问题描述】:

我有这个代码:

public void myMethod()
{
    int a = 10;
    int b = 20;
    Func<int, int, int> multiplyDelegate;
    multiplyDelegate = Multiply;
    multiplyDelegate += Multiply2;

    Console.WriteLine(multiplyDelegate(a,b));
}

public int Multiply(int x, int y)
{
    return x * y;
}
public int Multiply2(int x, int y)
{
    return x * y + 10;
}

通过运行 myMethod,我希望控制台显示“Multiply”和“Multiply2”这两种方法的返回,但只显示“Multiply2”方法的返回。我在这里做错了什么还是我误解了代表的概念?据我所知,委托是一组对方法的引用。

【问题讨论】:

  • 两个都调用但不写两个

标签: c# methods delegates


【解决方案1】:

来自Using Delegates (C# Programming Guide)

如果委托有返回值和/或输出参数,则返回 最后调用的方法的返回值和参数。

【讨论】:

    【解决方案2】:

    你是对的,委托可以存储方法并一次调用多个方法。除非您明确调用它们,否则它将返回最后一个。

    使用您的代码,这里有一个为您的所有方法集合显式调用的示例。

    var results = multiplyDelegate.GetInvocationList().Select(x => (int)x.DynamicInvoke(10, 20));
    foreach (var result in results)
        Console.WriteLine(result);
    

    编辑:

    这适用于函数 Func 而不是 Action。这是一个假设它是Action的示例

    foreach (Delegate action in multiplyDelegate.GetInvocationList())
    {
        action.DynamicInvoke(10, 20);
        // Do Something
    }
    

    第二个示例也适用于 Func

    【讨论】:

    • 感谢 Lostblue,成功了 :)
    【解决方案3】:

    我没有任何官方消息来源,但我认为您不能从一个委托调用中返回两个值。因此,使用最后返回的值。

    虽然只用到了最后一个返回值,但确实执行了这两个方法。我们可以通过在返回之前打印一些东西来证明这一点:

    public int Multiply(int x, int y)
    {
        Console.WriteLine("Hello1");
        return x * y;
    }
    public int Multiply2(int x, int y)
    {
        Console.WriteLine("Hello2");
        return x * y + 10;
    }
    

    Hello1 和 Hello2 都被打印出来了。

    【讨论】:

    • 我将您的代码复制到了我的文档中,我的控制台中只显示了 Hello2 和 190。
    • @RobinCox 我在 csharppad.com 上尝试过,它同时显示 Hello1 和 Hello2。也许这是 C# 6 的新行为,而您使用的是 C# 5?看到这个; csharppad.com/gist/d0a0c42badee28aa3e908376cd6e7fb5
    • 这很奇怪,因为我有 Visual Studio 2017
    【解决方案4】:

    只能返回一个对象,因为 Multiple2 是最后一个执行它的对象,所以它会在控制台中输出。

    没有办法改变它。

    你可以这样做:

    public void myMethod()
            {
                int a = 10;
                int b = 20;
                Action<int, int> multiplyDelegate;
                multiplyDelegate = Multiply;
                multiplyDelegate += Multiply2;
                multiplyDelegate(10, 20);
    
                Console.Read(); 
            }
    
            public void Multiply(int x, int y)
            {
                Console.WriteLine(x * 2);
            }
            public void Multiply2(int x, int y)
            {
                Console.WriteLine(x * y + 10);
            }
    

    【讨论】:

      【解决方案5】:

      我也有这个问题,并测试了一些东西,比如为委托设置方法的另一种方法,但最后唯一可用的方法是在每组之后写另一行:

      public void myMethod()
      {
          int a = 10;
          int b = 20;
          Func<int, int, int> multiplyDelegate;
          multiplyDelegate = Multiply;
          Console.WriteLine(multiplyDelegate(a,b));
      
          multiplyDelegate += Multiply2;
      
          Console.WriteLine(multiplyDelegate(a,b));
      }
      
      public int Multiply(int x, int y)
      {
          return x * y;
      }
      public int Multiply2(int x, int y)
      {
          return x * y + 10;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-05-13
        • 2016-11-10
        • 1970-01-01
        • 2015-01-30
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 2013-11-16
        • 1970-01-01
        相关资源
        最近更新 更多