Linq - 我如何在“select new”语句中使用“this”

时间:2011-08-12 17:19:59

标签: linq

编辑:

我正在递归地查询一些XML到对象中。每个对象都有一个子对象列表,如果它有一个子对象,则应该引用它。

示例XML:

<object attribute1="text" attribute2="text"/>    
<object attribute1="text" attribute2="text">
    <object attribute1="text" attribute2="text">    
    <object attribute1="text" attribute2="text">    
</object>

示例Linq:

    private static List<MyObject> ParseMyObjects(XElement node, MyObject p)
    {
        List<MyObject> myobjs = (from x in node.Elements("object")
                                select new MyObject {
                                    attribute1 = x.Attribute("attribute1 ").Value,
                                    attribute2 = x.Attribute("attribute2 ").Value,                                     
                                    subObjects = ParseMyObjects(x, this), // the "this" key word can't refer to the MyObject being created in the query, but is there some other way of doing this?
                                    parent= p
                                }).ToList();
        return myobjs;
    }

为了实现这一点,我在查询之后递归遍历MyObjects列表并设置每个父级(上面的“父”行被排除)。

如果可能的话,我更喜欢在Linq查询中使用新实例化对象的更优雅的解决方案。有什么想法吗?

修改 为了澄清(正如BrokenGlass在评论中所做的那样),代码注释所引用的 this 是在查询中创建的MyObject实例

3 个答案:

答案 0 :(得分:2)

this无法在标记为static的方法中使用。没有实例,因为该方法是静态的。

  

如果可能的话,我更喜欢在Linq查询中使用新实例化对象的更优雅的解决方案。有什么想法吗?

只需使用

中的XObject.Parent即可
parent = x.Parent

答案 1 :(得分:1)

如果您希望创建的Parent实例的MyObject成员指向实例本身,有两种方法可以实现此目的,而无需添加在Linq查询后迭代列表的代码:< / p>

1)添加一个为您设置的构造函数,例如默认构造函数

public MyObject() {
    this.Parent = this;
}

2)添加一个用于设置父级的fluent-interface样式方法,并在查询中调用它:

/* in class MyObject */
public MyObject WithSelfAsParent() {
    this.Parent = this;
    return this;
}

/* updated linq query */
List<MyObject> myobjs = (from x in node.Elements("object")
                                select new MyObject {
                                    attribute1 = x.Attribute("attribute1 ").Value,
                                    attribute2 = x.Attribute("attribute2 ").Value,                                     
                                    subObjects = ParseMyObjects(x),                                  

                                }.WithSelfAsParent()).ToList();

这些是否优于显式循环列表当然是品味问题。我可能只是保持简单并选择循环,除非默认情况下父指针与此相等的假设在MyObject类的上下文中是显而易见的,这使得在默认构造函数中将其设置为自然选择

答案 2 :(得分:0)

我的解决方案是利用MyObject上的subObjects属性集。

class MyObject {
....

private List<MyObject> _subObjects = new List<MyObject>();
public List<MyObject> subObjects 
{
    get { return _subObjects ; }
    set 
    { 
        _subObjects  = value;
        if(_subObjects != null)
        {
            foreach(MyObject o in _subObjects )
            {
                o.parent = this;
            }
        }
    }
}

....
}

如果有人知道在Linq语法中引用新创建/选定对象的方法,我会将您的答案标记为正确答案。