Вопрос
Как делегат хранит ссылку на функцию?Похоже, что исходный код ссылается на него как на объект, а способ, которым он вызывает метод, кажется отредактированным из исходного кода.Кто-нибудь может объяснить, как C # справляется с этим?
Original Post
Кажется, я постоянно борюсь с абстракциями, которые C # навязывает своим программистам.То, что меня раздражало, это запутывание функций / методов.Насколько я понимаю, все методы на самом деле являются анонимными методами, назначенными свойствам класса.По этой причине ни одна функция не имеет префикса типа данных.Например ...
void foo() { ... }
... будет написано в Javascript как ...
Function foo = function():void { ... };
По моему опыту, анонимные функции, как правило, плохая форма, но здесь они переполненына протяжении всего языкового стандарта.Поскольку вы не можете определить функцию с ее типом данных (и, по-видимому, подразумевается / обрабатывается компилятором), как хранить ссылку на метод , если тип никогда не объявляется?
Я очень стараюсь избегать Delegates
и его вариантов (Action
& Func
), потому что оба ...
- это еще одна абстракция от того, что на самом деле происходит
- ненужные накладные расходы, необходимые для создания экземпляров этих классов (которые, в свою очередь, несут свои собственные указатели на вызываемые методы).
Глядя на исходный код для Delegate.cs
, кажется, что ссылка на функцию просто называется Object
(см. Строки 23-25).
Если это действительно объекты, как мы их называем?Согласно следу delegate.cs
, он заходит в тупик по следующему пути:
Delegate.cs:DynamicInvoke()
> DynamicInvokeImpl()
> methodinfo.cs:UnsafeInvoke()
> UnsafeInvokeInternal()
> RuntimeMethodHandle.InvokeMethod()
> runtimehandles.cs:InvokeMethod()
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
Это действительно не объясняет, как он вызывается, если действительно метод является объектом.Такое ощущение, что это вовсе не код, а фактический вызываемый код удален из исходного репозитория.
Ваша помощь приветствуется.
Ответ на предыдущие комментарии
@ Эми: Я привел пример сразу после этого заявления, чтобы объяснить, что я имел в виду.Если функция имеет префикс типа данных, вы можете написать настоящую анонимную функцию и сохранить ее как свойство для объекта, например:
private Dictionary<string, Function> ops = new Dictionary<string, Function> {
{"foo", int (int a, int b) { return a + b } }
};
В таком виде C # не позволяет вам писатьистинные анонимные функции и стены, которые отключены за Delegates
и Lambda expressions
.
@ 500 Внутренняя ошибка сервера: Я ужеобъяснил, что я пытался сделать.Я даже смел это.Вы предполагаете, что здесь есть какой-то скрытый мотив;Я просто пытаюсь понять, как C # хранит ссылку на метод.Я даже предоставил ссылки на исходный код, чтобы другие могли прочитать код для себя и помочь ответить на вопрос.
@ Dialecticus: Очевидно, если я уже нашел типичный ответ в Google,только другое место, где можно найти ответ, который я ищу, будет здесь.Я понимаю, что это за пределами знаний большинства разработчиков C #, и именно поэтому я предоставил ссылки на исходный код.Вам не нужно отвечать, если вы не знаете ответа.