Разбираюсь в c# в частности с делегатами, возник вопрос зачем нужны делегаты если можно создать экземпляр класса и вызвать метод.
Экземпляр класса
class MainClass
{
public string Print3(string s)
{
return s + "hello bro";
}
public static void Main()
{
MainClass m = new MainClass();
m.Print3...
}
}
Делегат
delegate string Print2(string s);
class MainClass
{
static string Print3(string s)
{
return s + "hello bro";
}
public static void Main()
{
Print2 p = new Print2(Print3);
string s = p("hello");
}
}
Вопрос: Можно ли обойтись без делегатов?
Ответ: Да. Java, можно сказать, обходится без них, до версии 8 так и аналогов никаких не было. Да и во многих других языках аналогов нет.
Вопрос: Можно ли код, который использует делегаты, переписать без делегатов?
Ответ: Да. Например, в той же Java, до версии 8, всегда когда нужно было привязать слушатель к событию нужно было объявить класс. Выглядело это примерно так:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent clickevent) {
System.out.println("Button Clicked");
}
});
Вопрос: Для чего нужны делегаты?
Ответ: Это синтаксический сахар. Они позволяют писать код короче.
Например, аналог кода выше на C#:
button.Click += (s, e) => Console.WriteLine("Button clicked");
Делегаты тесно связаны с другими элементами языка:
Все это можно при желании реализовать самому через классы и интерфейсы, но этот функционал расширяет возможности языка, позволяет писать более короткий код.
Если можете написать код без делегатов — пишите. Но если тот же код можно написать быстрее и проще с делегатами было бы странно их не использовать.
Вообще, без большей части функционала языка можно обойтись: код, в котором используется наследование, можно переписать без него; классы можно переписать на процедурах и т.д. Любой код на C# можно переписать на ассемблере без потери производительности и функционала. Просто кода будет намного больше. В Brainfuck всего 8 инструкций и любой код на C# теоретически можно переписать на нем. Разница в производительности если будет, то она скорее будет связана с поддержкой оптимизаций на уровне ОС и процессоров чем с возможностями языка.
P.S. Последний раз про Java: в версии 8 ввели лямбда-выражения не вводя при этом понятия «делегат» и «событие» на уровне языка. Вместо делегатов используются интерфейсы. Из-за отстутствия поддержки на уровне языка операторы на них не определены и объявление выглядит чуть более громоздко, но возможности те же.
Один из примеров, когда без делегатов вовсе не обойтись - взаимодействие с кодом на процедурных языках программирования, который оперирует указателями на функции. Например, см. данный ответ, в котором определяется делегат
delegate IntPtr KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
который передается в неуправляемую функцию SetWindowsHookEx в качестве параметра HOOKPROC. Исключительно на классах (через шаблон "Наблюдатель") это не реализовать.
С помощью делегатов можно передать ссылку на метод или сам метод как параметр.
Например:
User GetUser(uint id, Action<Exception> onError)
Этот метод возвращает объект User, и если произошла ошибка то выполняет НАШ код передавая в него Exception
try {} catch(Exception e) {
OnError?.Invoke(e);
}
Конкретно в Вашем случае можно не создавать новый делегат, а воспользоваться встроенным Action.
void Print(Action<string> print2) {
print2?.Invoke("myMessage");
}
Вызвать такой метод можно следующим образом:
void Print2((e) => { Console.WriteLn(e); }
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Не получается настроить references в MySQL, не понимаю что делаю не правильно