C# имеет operator()
, который он называет Invoke
.
В любое время, когда вы определяете тип delegate
, вы определяете класс с методом с именем Invoke
и можете использовать синтаксис вызова функции с экземплярами этого класса, что приведет к вызову Invoke
. Подобно operator()
, делегаты C# Invoke
могут иметь почти любую подпись функции.
В отличие от C++ operator()
, C# не позволяет определять произвольные другие члены того же класса, который определяет Invoke
. Можно сказать, что C# обеспечивает соблюдение принципа единой ответственности. Однако это не является основным ограничением, поскольку делегаты C# подключаются к другому объекту, который обеспечивает хранение состояния для объекта функции.
Более тяжелой (в том смысле, что не существует никакой простой обходной путь) ограничение на C# Invoke
по сравнению с С ++ operator()
является то, что C# делегат Invoke
методы не могут быть перегружены, ни полиморфными. Это является следствием необходимости переадресации вызова методу на другой объект, но это предотвращает использование некоторых сценариев использования с помощью пользовательских функторов C++.
Было бы интересно посмотреть, что произойдет, если вы определили перегруженный метод Invoke
с использованием MSIL. Конечно, вы бы смутили компилятор C#, если бы попытались использовать такой класс делегата и, вероятно, также среду CLR. Так что это скорее курионос, чем практический подход.
C++ std::function
очень похож на типы делегатов C# в возможностях и ограничениях. Он также переадресовывает вызовы и не является полиморфным по сигнатуре вызова. Ditto для C++ 11 lambdas, хотя C++ 14 lambdas позволит шаблоны operator()
и полиморфизм типа call-site (в отличие от C# lambdas, которые допускают только полиморфизм точки определения).
Очень мало. Лямбдас и делегаты делают это почти бессмысленным. –
Вы размываете линию между функциями и объектами (которые уже есть делегаты) и путают корпоративных программистов-дронов, приводя к катастрофе библейских масштабов (огонь и сера, спускающиеся с неба!) Реки и моря кипят! Сорок лет тьмы! Землетрясения , вулканы! Мертвые поднимаются из могилы! Человеческая жертва! Собаки и кошки, живущие вместе! Массовая истерия!) Я думаю, мы все можем согласиться, что лучше избегать этого. –
BTW, в C#, 'operator()' написано 'Invoke'. –