Как на самом деле работает func
Поэтому, когда я возвращаю объект, под обложками я думаю, что он возвращает адрес памяти этому объекту (или объекту, содержащему адрес памяти), на который вы можете ссылаться и использовать.
Но что на самом деле происходит, когда вы возвращаете функцию?
Как ваше приложение узнает, какой экземпляр объекта использовать с этой функцией?
Мой инстинкт подсказывает мне, что ссылка на экземпляр объекта передается вместе с функцией, но происходит ли это на самом деле?
Я не могу кажется, нашел много на эту тему.
Edit :
Чтобы уточнить, я спрашиваю, когда метод возвращает функцию
5 ответов:
A
Funcявляется делегатом-типом объекта, который связан с определенной сигнатурой метода и обычно привязан к определенному методу с этой сигнатурой. Это может быть либоstatic, либо метод экземпляра, и он может быть универсальным или нет; во всех случаях экземпляр делегата содержит всю информацию, необходимую для вызова метода.
A
Funcявляется делегатом, иDelegateэкземпляры инкапсулируютMethodInfoи необязательный целевой объект для вызова метода при вызове.
У вас есть и то и другое
Funcи ещеAction, которые являются встроенными делегатами. Разница между ними заключается в том, чтоFuncвозвращает тип, аAction- нет.Вы найдете
Funcиспользует сильно вIEnumerable(T) Interface, с помощью методов расширения Linq.Взгляните на этот пример из предоставленной ссылки MSDN...
Func<string, string> selector = str => str.ToUpper(); string[] words = { "orange", "apple", "Article", "elephant" }; IEnumerable<String> aWords = words.Select(selector); foreach (String word in aWords) Console.WriteLine(word);Это по существу использует функцию селектора для преобразования каждой из строк в словах в верхний регистр.
Func<T>это просто делегат. Если он установлен в метод экземпляра, то он [волшебным образом] получает правильное значениеthisпри вызове. Если задан статический метод, то нетthis. И если он установлен в closure/lambda, закрытие "захватывает" эти переменные в области во время закрытия. лексический объем (с некоторыми оговорками: вещи не всегда работают так, как вы думаете, что они могли бы).Отредактировано и добавлено:
Из стандарта C#, ISO 23270: 2006 Информационные технологии - Языки Программирования-C#, §8.10:
8.10 делегаты
Делегаты включают сценарии, которые некоторые другие языки рассматривали с помощью функции указатели. Однако, в отличие от указателей функций, делегаты являются объектно-ориентированными и типобезопасными.
Объявление делегата определяет класс, производный от класса
System.Delegate. Экземпляр делегата инкапсулирует один или несколько методов, каждый из которых называется а вызываемый сущность. Например, методы, вызываемая сущность состоит из экземпляра и метод на этом примере. Для статических методов вызываемая сущность состоит из всего лишь метод. При наличии экземпляра делегата и соответствующего набора аргументов можно вызвать все методы этого экземпляра делегата с этим набором аргументов.Более подробно, другой стандарт, ISO 23271: 2006 Информационные технологии-инфраструктура общего языка (CLI) разделы I-VI в §14.6 сказано:
Конструктор экземпляра (именованный
.ctorи помеченныйspecialnameиrtspecialname, §10.5.1) должны принимать ровно два параметра, первый из которых имеет типSystem.Object, и второе, имеющее типSystem.IntPtr. Когда фактически вызывается (черезnewobjраздел III), первым аргументом должен быть экземпляр класса (или один из его производных классов), который определяет целевой метод, и второй аргумент будет указателем метода на метод, который будет называемый.Это нето волшебство.
Когда вы создаете анонимный метод, например, назначенный
Func<T>, локальные объекты, используемые внутри него, поднимаются в класс. Рассмотрим это:int GetIncremented() { int x = 0; Func<int> increment = () => ++x; increment(); return x; }За кулисами будет создано что-то вроде этого:
Вот почему параметрыsealed class FuncData { public int x = 0; public int FuncIncrement(FuncData data) { return ++data.x; } } int GetIncremented() { FuncData data = new FuncData(); Func<int> increment = new Func<int>(data.FuncIncrement); increment(); return data.x; }outиrefНельзя использовать с анонимными методами: нельзя хранитьoutилиrefв качестве переменной-члена в классе.
Comments