Многоадресные делегаты должны иметь тип возврата void. Зачем?

Многоадресные делегаты должны иметь возвращаемый тип void. В противном случае будет выдано исключение.

Я хочу знать, в чем причина этого, что, если несколько методов могут иметь тот же тип возврата, что и делегат?

3 ответа

Решение

Предпосылка неверна; работает нормально

Func<int> func = delegate { Console.WriteLine("first part"); return 5; };
func += delegate { Console.WriteLine("second part"); return 7; };
int result = func();

Это многоадресный делегат с не пустым результатом, работающий нормально. Из консоли видно, что обе части выполнены. Результат последнего элемента - тот, который возвращен. Мы можем продемонстрировать, что это настоящий многоадресный делегат:

if(func is MulticastDelegate) Console.WriteLine("I'm multicast");

и он будет писать "Я многоадресный" даже после первой строки (когда указан только один метод).

Если вам нужно больше контролировать отдельные результаты, используйте GetInvocationList():

foreach (Func<int> part in func.GetInvocationList())
{
    int result = part();
}

что позволяет увидеть каждый отдельный результат.

В терминологии IL:

.class public auto ansi sealed Func<+ TResult>
    extends System.MulticastDelegate`

что сказать: Func<T> наследуется от MulticastDelegate, По сути, все делегаты в.NET являются многоадресными делегатами. Возможно, вы сможете получить не-многоадресный делегат в управляемом C++, я не знаю. Но, конечно, не из C#.

Следующий ответ на самом деле неверен, потому что вы в настоящее время * можете * иметь многоадресные делегаты с не возвращаемым типом возврата (жюри все еще не знает, было ли это всегда так). Тем не менее, он отвечает на вопрос "Почему язык может запрещать таких делегатов?", Поэтому я оставляю его для полноты.

А теперь иди и проголосуй, Марк.


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

  • вернуть значение первого метода в порядке вызова (но порядок вызова IIRC не указан, так как это будет работать?)
  • вернуть значение последнего метода, как указано выше
  • вернуть единственное отдельное значение, возвращаемое всеми делегатами; выбросить исключение, если не все из них согласны

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

 class Program
{
    // i am going to add and subtract two num but i wanna get result in string the same thing you can do for int and what ever you want
      delegate string mydeledagte(int a,int b);
      delegate string d(int s, int t);
    static void Main(string[] args)
    {
        mydeledagte ab = new mydeledagte(ad);
        mydeledagte d= new mydeledagte(sub);
        mydeledagte multi = ab + d;

        foreach (mydeledagte individualMI in multi.GetInvocationList())
        {
            string retVal = individualMI(3, 5);
            Console.WriteLine("Output: " + retVal);
            Console.WriteLine("\n***developer of KUST***");
            Console.ReadKey();
        }
    }
    static string ad(int a, int b)
    {

        return (a + b).ToString();

    }
    static string sub(int a, int b)
    {

        return (a - b).ToString(); ;
    }
}
Другие вопросы по тегам