func如何正常工作

时间:2013-12-12 20:13:55

标签: c# func

因此,当我返回一个对象时,我认为它将内存地址返回给您可以引用和使用的对象(或包含内存地址的对象)。

但是当你返回一个函数时实际发生了什么?

您的应用如何知道该func使用哪个对象实例?

我的直觉告诉我,对象实例引用与func一起传递,但实际发生的是什么?

我似乎无法在这个主题上找到太多。

修改: 为了澄清,我问一个方法何时返回一个函数

5 个答案:

答案 0 :(得分:6)

Func是委托 - 一种与特定方法签名关联的对象,通常绑定到具有该签名的特定方法。这可能是static或实例方法,它可能是通用的或不是通用的;在所有情况下,委托实例都包含调用该方法所需的所有信息。

答案 1 :(得分:5)

Func是一个委托,Delegate个实例封装了一个MethodInfo和一个可选的目标对象,以便在调用时调用该方法。

答案 2 :(得分:2)

Func<T>只是一名代表。如果它被设置为实例方法,那么,它[神奇地]在调用时获得正确的this值。如果设置为静态方法,则没有this。如果将其设置为closure / lambda,则闭包会在关闭时“捕获”范围内的变量。词汇范围(有一些警告:事情并不总是以你认为的方式运作)。

编辑添加:

来自C#标准,ISO 23270:2006 信息技术 - 编程语言 - C#,§8.10:

  

8.10代表

     

代理启用其他语言通过函数解决的方案   指针。但是,与函数指针不同,委托是面向对象的,类型安全的。

     

委托声明定义了一个派生自类System.Delegate的类。   委托实例封装了一个或多个方法,每个方法都被称为    可调用实体 。例如,方法,可调用实体由实例组成   和该实例上的方法。对于静态方法,可调用实体由just组成   一个方法。给定一个委托实例和一组适当的参数,可以调用   所有委托实例的方法都包含那组参数。

更详细地说,另一个标准,ISO 23271:2006 信息技术 - 公共语言基础结构(CLI)分区I到VI 在§14.6中说明:

  

实例构造函数(名为.ctor并标记为specialnamertspecialname,   参见§10.5.1)应该采用两个参数,第一个参数类型为System.Object,   第二个类型为System.IntPtr。实际调用时(通过newobj   指令,参见Partition III),第一个参数应该是类的一个实例   (或其派生类之一)定义目标方法,第二个参数   应该是一个指向要调用的方法的方法指针。

这不是 魔法。

答案 3 :(得分:1)

当您创建匿名方法(例如分配给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;
}

这就是为什么outref参数不能与匿名方法一起使用的原因:您不能将outref存储为成员变量类。

答案 4 :(得分:1)

您同时拥有FuncAction,这些都是内置代理。它们之间的区别在于Func返回一种类型而Action没有。

您会发现Func使用Linq扩展方法在IEnumerable(T) Interface中大量使用。

从提供的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);

这主要使用 Selector Func 将单词中的每个字符串转换为大写。