从LINQ到XML选择查询实现动态对象的简短方法?

Joh*_*n K 5 .net c# initialization linq-to-xml expandoobject

是否有一个初始化语法ExpandoObject,我可以在LINQ to XML查询中使用它以简化目的?

注意:查询的结果旨在传递到当前程序集的范围之外,因此匿名类型是不可能的(请参阅此处的原因).

我正在尝试使用如下的简短语法来创建动态/ expando对象:

public IEnumerable<dynamic> ParseUserXml(string strXmlUser) {

var qClients =
    from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
    // client object

    // I cannot get ExpandoObject to initialize inline 
    select new ExpandoObject() {     // try initialization syntax, COMPILE ERR
        OnlineDetails = new
        {
            Password = client.Element(XKey.onlineDetails).
                Element(XKey.password).Value,
            Roles = client.Element(XKey.onlineDetails).
                Element(XKey.roles).Elements(XKey.roleId).
                Select(xroleid => xroleid.Value)
            // More online detail fields TBD
        },

        // etc ....

        // YIELD DYNAMIC OBJECTS BACK THROUGH IEnumerable<dynamic>...
        foreach (var client in qClients)
        {
            yield return client;
        }
Run Code Online (Sandbox Code Playgroud)

使代码工作的更多参与解决方案可能是:

  • 创建具体类并初始化它(但我不想创建一堆).
  • 使用匿名类型并将其成员复制到动态对象(有点多余)并返回动态对象

是否有一个同样短的语法来实现我想要通过错误的代码做的事情,或者我是否必须以某种方式扩展代码库以获得所需的结果?

Joh*_*n K 0

我最终使用了Jon Skeet 在相关问题中的代码答案之一。代码示例复制到此处供后代使用。它使用原始类而不是查询语法。

// Code answer by Jon Skeet.
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; 
       });
Run Code Online (Sandbox Code Playgroud)