Как получить список результатов вызова делегата? - PullRequest
6 голосов
/ 20 июня 2011

Мне нужно немного больше узнать о делегатах и ​​дизайне языка C #.

Допустим, у меня есть MulticastDelegate, который реализует универсальный делегат и содержит несколько вызовов:

Func<int> func = null;
func += ( )=> return 8;
func += () => return 16;
func += () => return 32;

Теперь этот код вернет 32:

int x = func(); // x=32

Я хотел бы знать, существует ли (или лучше я должен спросить, почему его нет!) Функция языка C #используя который можно получить доступ к результатам всех вызовов делегата, это значит получить список ({8,16,32})?

Конечно, можно сделать то же самое с помощью подпрограмм .NET Framework,Примерно так будет работать:

public static List<TOut> InvokeToList<TOut>(this Func<TOut> func)
{
    var returnValue = new List<TOut>();
    if (func != null)
    {
        var invocations = func.GetInvocationList();
        returnValue.AddRange(invocations.Select(@delegate => ((Func<TOut>) @delegate)()));
    }
    return returnValue;
}

Но я не могу понять из системы, что должен быть лучший способ, по крайней мере без приведения (действительно, почему MulticastDelegate не является универсальным, когда делегаты)

Ответы [ 3 ]

6 голосов
/ 20 июня 2011

Нет, лучшего способа нет - когда вы вызываете многоадресный делегат, результат является просто результатом последнего делегата. Вот как это происходит на уровне фреймворка.

Многоадресные делегаты в основном полезны для обработчиков событий. Относительно редко использовать их для подобных функций.

Обратите внимание, что Delegate также не является универсальным - только отдельные типы делегатов могут быть универсальными, поскольку арность типа может изменяться в зависимости от типа. (Например, Action<T> и Action<T1, T2> на самом деле не связаны между собой.)

2 голосов
/ 20 июня 2011

Вы можете выполнить то, что вы хотите, если вы не используете Func<int>, но Действие, которое принимает метод в качестве параметра, который обрабатывает возвращаемые значения. Вот небольшой пример:

    static Action<Action<int>> OnMyEvent=null;

    static void Main(string[] args)
    {
        OnMyEvent += processResult => processResult(8);
        OnMyEvent += processResult => processResult(16);
        OnMyEvent += processResult => processResult(32);

        var results = new List<int>();
        OnMyEvent(val => results.Add(val));

        foreach (var v in results)
            Console.WriteLine(v);

    }
1 голос
/ 20 июня 2011

Нет способа получить а) исключения б) возвращать значения от делегатов, только путем прослушивания в списке результатов.Другой способ - просто иметь список делегатов и управлять им вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...