从lambda /代码解释返回匿名类型



此代码来自stackoverflow成员mr.Lukazoid。我想知道这是怎么回事。我觉得有点奇怪,你怎么这样调用一个方法。TResult的作用是什么?

public static string[] Foo<T, TResult>(Expression<Func<T, TResult>> func)
{
return typeof(TResult).GetProperties().Select(pi => pi.Name).ToArray();
}
Foo((Person x) => new { x.LastName, x.DateOfBirth });

谢谢你。

解决方案是尝试以类型化的方式从类中获取属性名称的子集。

有几种方法可以做到这一点,但是作者选择了一种非常狡猾的方法,利用泛型推理来节省委托/表达式调用的成本。这就是为什么func从来不被称为…

为了实现这一点,作者依赖于以下事实:泛型类型参数静态编译的,并且可以通过方法的参数推断

本例中通用参数<T, TResult>T(Person x)(lambda的参数侧)推导出TResultnew { x.LastName, x.DateOfBirth }(lambda的主体)推导出

由于泛型是编译时语言特性,该方法可以访问typeof(TResult)的自反属性…不需要调用/执行表达式

看起来很棒,工作完成了。然而,同样的事情也可以用Func委托来完成,而且成本要低得多

public static string[] Foo2<T,TResult>(Func<T, TResult> _)
=> typeof(TResult).GetProperties().Select(pi => pi.Name).ToArray();

122.7 ns2.47 ns2.31 ns
StdDev
Expression2,852.9 ns47.68 ns44.60 ns
Func

Func<T, TResult>表示这样声明的函数:

TResult functionName(T parameter).

也就是说,TResult是函数返回值的类型。上述类型(本例中为T)是传递给函数的参数类型。

在这段代码中,Foo((Person x) => new { x.LastName, x.DateOfBirth });,方法Foo被传递给签名为Func<Person, AnonymousTypeContainingNameAndBirth>的匿名方法

也就是说,TResult就是AnonymousTypeContainingNameAndBirth

由于Foo方法期望Expression<Func<T, TResult>>,该匿名方法实际上在传递给Foo之前转换为表达式,但这是另一个讨论的故事。

您提供的代码返回string[] { "LastName", "DateOfBirth" }

相关内容

  • 没有找到相关文章

最新更新