Меня очень интересует это ограничение делегатов C#. Возьмите следующий код, который не компилируется:
class Program
{
delegate void Foo(string s);
static void Main(string[] args)
{
Foo f = Test; // Error
f("Hello");
}
static int Test(string s)
{
return s.Length;
}
}
Ошибка здесь в том, что делегат Foo
не имеет возвращаемого типа, поэтому его нельзя использовать для создания ссылки на функцию Test
.
Однако почему это проблема? Очевидно, что если бы кто-то вызывал Test
через делегат f
, он не имел бы доступа к возвращаемому значению Test
, что совершенно справедливо, но мне кажется, что компилятор все равно мог бы генерировать type безопасный код, просто игнорируя возвращаемое значение, возможно, даже имея возможность оптимизировать этот случай.
Очевидно, что если бы ситуация была обратной, и Foo
указал, что нужно вернуть string
, а Test
вернул void
, у нас возникла бы проблема. Итак, я полностью согласен с тем, что этот случай должен приводить к ошибке компилятора. Однако почему нельзя int Test(string)
неявно сопоставить делегата void Foo(string)
?
Я ищу один из двух возможных ответов: во-первых, логическая проблема с предоставлением этой возможности. Есть ли случай, когда игнорирование типа возвращаемого значения при вызове метода через делегата может привести к небезопасному состоянию? Или, во-вторых, ссылка на спецификацию C#, в которой поясняется, почему эта реализация будет нарушать спецификацию.