Делегат Func не объединяет методы

Представим себе простые вызовы делегатов:

void Main()
{
    Func<int, int, string> tfunc = null;
    tfunc += Add; // bind first method
    tfunc += Sub; // bind second method 

    Console.WriteLine(tfunc(2, 2));
}

private string Add(int a, int b)
{
    return "Add: " + (a + b).ToString();
}

private string Sub(int a, int b)
{
    return "Sub: " + (a - b).ToString();
}

Результат этой программы:

Sub: 0

Итак, почему метод Add не был вызван? Я ожидаю вызова метода Add, а затем метода Sub.

2 ответа

Решение

Добавить было правильно приковано и вызвано, посмотрите на результат

void Main()
{
    Func<int, int, string> tfunc = null;
    tfunc += Add; // bind first method
    tfunc += Sub; // bind second method 

    Console.WriteLine(tfunc(2, 2));
}

private string Add(int a, int b)
{
    Console.WriteLine("Inside Add");
    return "Add: " + (a + b).ToString();
}

private string Sub(int a, int b)
{
    Console.WriteLine("Inside Sub");
    return "Sub: " + (a - b).ToString();
}

Это:

Inside Add
Inside Sub
Sub: 0

То, что не связано, потому что нет доступа к нему, является результатом метода Add. Делегаты, которые возвращают значение, в случае объединения в цепочку возвращают значение последнего вызванного метода, то есть последнего метода, который был добавлен к делегату.

Это указано в части 15.4 спецификации языка C# 4.0

Вызов экземпляра делегата, чей список вызовов содержит несколько записей, продолжается, вызывая каждый из методов в списке вызовов синхронно по порядку.... Если вызов делегата включает выходные параметры или возвращаемое значение, их окончательное значение будет получено при вызове последнего делегата в списке.

Проблема в том, что возвращаемое значение не передается между вызовами метода, поэтому выходные данные захватывают только последнюю возвращенную строку. Т.е. возврат Add теряется.

Другие вопросы по тегам