Если делегаты являются абстрактными, то как это позволяет создавать объекты
Вот ссылка на одно из лучших эссе на делегатах С#, которые я нашел, и автор делает отличную работу по предоставлению развлекательного и информативного пошагового руководства, как работают делегаты и почему мы их используем.
http://www.sellsbrothers.com/writing/default.aspx?content=delegates.htm
делегат - это указатель безопасной функции типа. Это ссылочный тип в С#.
delegate result-type identifier ([parameters]);
Однако класс Делегат не является типом делегата, это класс, используемый для получения типов делегатов, поэтому он абстрактный ( проверьте больше разъяснений).
Делегат выглядит как указатель функции типа, конечно, чтобы понять, что вам нужно знать, что такое указатель на функцию, и почему важны типы безопасности, но это больше, чем это.
Под обложками делегат - это класс с методом Invoke, во время компиляции создается метод Invoke, чтобы иметь ту же подпись, что и определение делегата. Так что если я делаю
делегировать int MyDelegate (строка s);
У меня получилось бы что-то вроде
class MyDelegate : MulticastDelegate
{
int Invoke(string s) {...}
}
Я могу использовать это в коде вроде этого
int SomeFunc(string s)
{
// do something with s and return an int
}
MyDelegate del = new MyDelegate(SomeFunc);
то либо
int a = del.Invoke("Foo");
или просто
int a = del("Foo");
Это последнее использование, которое делает его похожим на указатель на функцию ('del' указывает на функцию SomeFunc), и он набирает тип, потому что он принимает и возвращает только определенные типы (правила немного сложнее, чем это).
У вас также есть другие способы вызова делегатских анонимных методов и lambdas, но это выходит за рамки этого
Многое происходит с маской компилятора, например, превращением определения делегата в определение класса и превращением вызова метода в вызов Invoke.
НТН
Здесь отличная статья о делегатах, а затем обсуждается Лямбда-выражения, подчеркивающие взаимосвязь между ними.
Надеюсь, что это поможет.