开发者

Linq - How can i use "this" inside of a "select new" statement

Edited:

I'm querying some XML into objects recursively. Each object has a list of sub objects, and should refer to it's parent if it has one.

Example XML:

<object attribute1="text" attribute2="text"/>    
<object attribute1="text" attribute2="开发者_运维知识库text">
    <object attribute1="text" attribute2="text">    
    <object attribute1="text" attribute2="text">    
</object>

Example 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;
    }

To accomplish this currently, I am recursively traversing the MyObjects list AFTER it has been queried and setting each parent (the "parent" line above is excluded).

I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?

Edit: To clarify (as BrokenGlass did in a comment), the this that the code comment is referring to is the instance of MyObject that is being created within the query


this can't work in a method marked static ever. There is no instance because the method is static.

I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?

Just use XObject.Parent as in

parent = x.Parent


If you want the Parent member of the created MyObject instance to point to the instance itself, there are two ways to achieve this without adding code that iterates over the list after the Linq query:

1) Add a constructor that sets it up for you, e.g. the default constructor

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

2) Add a fluent-interface style method for setting the parent, and invoke it in the query:

/* 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();

Whether these are better than explicitly looping over the list is of course a matter of taste. I would probably just keep it simple and choose the loop, unless the assumption that the parent pointer is equal to this by default is obvious in the context of your MyObject class, which makes setting it in the default constructor the natural choice.


The solution for me was to harness the set of the subObjects property on MyObject.

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;
            }
        }
    }
}

....
}

If anyone does know of a way to reference the newly created/selected object within the Linq syntax, I will mark your answer as the corrrect one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜