我们说我有两个班级:
public Foo
{
public List<Foo> Childs { get; set; }
public Bar BarObj { get; set; }
public int Level { get; set; }
}
public Bar
{
public List<Foo> Childs { get; set; }
}
现在我想从“Foo”对象的集合中获取嵌套级别
我目前的工作方法如下:
int currentLevel = 0;
public void ApplyNestingLevel(List<Foo> list)
{
foreach(var item in list)
{
item.Level = currentLevel;
if(item.Childs.Count > 0 || item.BarObj.Childs.Count > 0)
{
currentLevel++;
}
ApplyNestingLevel(item.Childs);
ApplyNestingLevel(item.BarObj.Childs);
}
}
我怎么能让这更“优雅/简单”?
答案 0 :(得分:3)
存储对父项的引用,并使Level属性递归。
我在下面的代码示例中添加了一个示例和一些其他设计建议。希望这可以帮助。仅供参考,这与“四人帮”的Composite Pattern设计完全相同,对于那些认真考虑OOP的人来说,这应该是必读的。
Design Patterns: Elements of Reusable Object-Oriented Software, on Amazon.com
public class Foo
{
public Foo(Foo parent = default(Foo))
{
this.parent = parent;
this.children = new List<Foo>();
}
private readonly Foo parent;
private readonly List<Foo> children;
public int Level { get { return ReferenceEquals(parent,null) ? 0 : parent.Level + 1; } }
// don't expose the actual list... see below for why
public IEnumerable<Foo> Children { get { foreach(Foo child in this.children) yield return child; } }
// instead of exposing the child object list
// declare an explicit method with any parameters
// necessary. this allows you to enforce the invariant
// condition that all objects in a children collection
// will have their parent reference set to their
// actual parent
public void AddChild()
{
Foo newChild = new Foo(parent:this);
this.children.Add(newChild);
}
// if you need the ability to remove items as well,
// you can expose a remove method too. Just make
// sure that you validate expected preconditions
public int RemoveChild(Foo childToRemove)
{
if(ReferenceEquals(childToRemove,null)) throw new ArgumentNullException("childToRemove");
if(!ReferenceEquals(this,childToRemove.parent)) throw new ArgumentException("The object cannot be removed because the current object is not the correct parent.","childToRemove");
return children.RemoveAll((Foo existentChild) => existentChild.Equals(childToRemove));
}
}
答案 1 :(得分:3)
public void ApplyNestingLevel(Foo f)
{
ApplyNestingLevel(f, 0);
}
public void ApplyNestingLevel(Foo f, int level)
{
if(f == null) { return; }
f.Level = level
if(f.Childs != null) {
foreach(Foo child in f.Childs)
{
ApplyNestingLevel(child, level + 1);
}
}
if(f.BarObj != null && f.BarObj.Childs != null) {
foreach(Foo child in f.BarObj.Childs)
{
ApplyNestingLevel(child, level + 1);
}
}
}