Как на самом деле работает func



Поэтому, когда я возвращаю объект, под обложками я думаю, что он возвращает адрес памяти этому объекту (или объекту, содержащему адрес памяти), на который вы можете ссылаться и использовать.



Но что на самом деле происходит, когда вы возвращаете функцию?



Как ваше приложение узнает, какой экземпляр объекта использовать с этой функцией?



Мой инстинкт подсказывает мне, что ссылка на экземпляр объекта передается вместе с функцией, но происходит ли это на самом деле?

Я не могу кажется, нашел много на эту тему.



Edit :
Чтобы уточнить, я спрашиваю, когда метод возвращает функцию

458   5  
c#

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

    Ничего не найдено.