Использование делегатов С# с методами с дополнительными параметрами

Есть ли шанс заставить этот код работать? Конечно, я могу сделать второе определение Foo, но я думаю, что это будет немного не изящно;)

delegate int Del(int x);

static int Foo(int a, int b = 123)
{ 
    return a+b; 
}

static void Main()
{
    Del d = Foo;
}

Ответ 1

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

Чтобы заставить его работать, вам нужно либо перегрузить ваш метод Foo() (как вы сказали), либо объявить делегата с необязательным параметром:

delegate int Del(int x, int y = 123);

Кстати, учтите, что если вы объявляете разные значения по умолчанию в своем делетете и методе реализации, используется значение по умолчанию, определенное типом делегата.

То есть, этот код печатает 457 вместо 124, потому что d is Del:

delegate int Del(int x, int y = 456);

static int Foo(int a, int b = 123)
{ 
    return a+b; 
}

static void Main()
{
    Del d = Foo;

    Console.WriteLine(d(1));
}

Ответ 2

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

В вашем случае метод Foo по-прежнему объявляется как принимающий два аргумента int в качестве входных данных. Нет версии Foo, которая может быть вызвана только с одним параметром (помните, компилятор заполняет пробелы для вас там). Любые делегаты, используемые для вызова методов с необязательными параметрами, должны явно включать все параметры для соответствия сигнатуре.

Ответ 3

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

Смотрите этот вопрос: Дополнительные параметры для делегатов не работают должным образом