编辑:
我正在递归地查询一些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实例
答案 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语法中引用新创建/选定对象的方法,我会将您的答案标记为正确答案。