创建LINQ查询委托实例内联的效率? [英] Efficiency of creating delegate instance inline of LINQ query?

查看:108
本文介绍了创建LINQ查询委托实例内联的效率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是两个例子,做同样的事情用不同的方式。我对它们进行比较。

Following are two examples that do the same thing in different ways. I'm comparing them.

为了一个例子,定义任何方法来创建并返回一个 ExpandoObject 的XElement 根据业务逻辑:

For the sake of an example, define any method to create and return an ExpandoObject from an XElement based on business logic:

var ToExpando = new Func<XElement, ExpandoObject>(xClient =>
{
    dynamic o = new ExpandoObject();    
    o.OnlineDetails = new ExpandoObject();
    o.OnlineDetails.Password = xClient.Element(XKey.onlineDetails).Element(XKey.password).Value;
    o.OnlineDetails.Roles = xClient.Element(XKey.onlineDetails).Element(XKey.roles).Elements(XKey.roleId).Select(xroleid => xroleid.Value);
    // More fields TBD.
}

从一个LINQ调用上述委托XML查询:

Call the above delegate from a LINQ to XML query:

var qClients =
    from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
    select ToExpando(client);


2版

完成所有的LINQ查询,包括创建和调用函数功能的委托。


Version 2

Do it all in the LINQ query, including creation and call to Func delegate.

var qClients =
from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
select (new Func<ExpandoObject>(() =>
        {
            dynamic o = new ExpandoObject();
            o.OnlineDetails = new ExpandoObject();
            o.OnlineDetails.Password = client.Element(XKey.onlineDetails).Element(XKey.password).Value;
            o.OnlineDetails.Roles = client.Element(XKey.onlineDetails).Element(XKey.roles).Elements(XKey.roleId).Select(xroleid => xroleid.Value);
            // More fields TBD.
  return o;
  }))();


考虑委托创建在选择部分,是第2版的低效?它是管理或由C#编译器或运行时优化,都不会有问题?


Considering delegate creation is in the select part, is Version 2 inefficient? Is it managed or optimized by either the C# compiler or runtime so it won't matter?

我喜欢版2为它的气密性(保持在查询中的对象创建逻辑),但也知道根据什么编译器或运行时就可​​能不是可行的。

I like Version 2 for its tightness (keeping the object creation logic in the query), but am aware it might not be viable depending on what the compiler or runtime does.

推荐答案

后一种方法看起来pretty的可怕的我。我相信,它必须真正建立一个新的委托作为你每次捕捉不同的客户端每一次,但我个人不会做它在所有的方式。既然你已经在那里真正的声明,为什么不写一个正常的方法是什么?

The latter approach looks pretty horrible to me. I believe it will have to genuinely create a new delegate each time as you're capturing a different client each time, but personally I wouldn't do it that way at all. Given that you've got real statements in there, why not write a normal method?

private static ToExpando(XElement client)
{
    // Possibly use an object initializer instead?
    dynamic o = new ExpandoObject();    
    o.OnlineDetails = new ExpandoObject();
    o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
                                     .Element(XKey.password).Value;
    o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
                                  .Element(XKey.roles)
                                  .Elements(XKey.roleId)
                                  .Select(xroleid => xroleid.Value);
    return o;
}

,然后用它查询:

and then query it with:

var qClients = xdoc.Root.Element(XKey.clients)
                        .Elements(XKey.client)
                        .Select(ToExpando);

我会的的更关心的code比创建代表的表现,这是可读性一般pretty的快。我不认为有任何需要使用几乎同样多的lambda表达式,你现在似乎热衷于这样做。想想看,当你回来这个code。在一年的时间。难道你真的打算找到嵌套的lambda更容易理解比法?

I would be much more concerned about the readability of the code than the performance of creating delegates, which is generally pretty quick. I don't think there's any need to use nearly as many lambdas as you currently seem keen to do. Think about when you come back to this code in a year's time. Are you really going to find the nested lambda easier to understand than a method?

(顺便说一下,该转换逻辑分离成方法使得容易单独测试...)

(By the way, separating the conversion logic into a method makes that easy to test in isolation...)

编辑:即使你的执行的想要做这一切在LINQ EX pression,你为什么如此热衷于创造间接的另一个层面?正因为查询EX pressions不允许lambda表达式?假设你在做什么,但一个简单的选择,这是很容易对付:

Even if you do want to do it all in the LINQ expression, why are you so keen to create another level of indirection? Just because query expressions don't allow statement lambdas? Given that you're doing nothing but a simple select, that's easy enough to cope with:

var qClients = xdoc.Root
           .Element(XKey.clients)
           .Elements(XKey.client)
           .Select(client => {
               dynamic o = new ExpandoObject();
               o.OnlineDetails = new ExpandoObject();
               o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
                                                .Element(XKey.password).Value;
               o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
                                             .Element(XKey.roles)
                                             .Elements(XKey.roleId)
                                             .Select(xroleid => xroleid.Value);
               return o; 
           });

这篇关于创建LINQ查询委托实例内联的效率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆