gpt4 book ai didi

c# - 如何从字符串表示形式创建表示 namespace 的树

转载 作者:行者123 更新时间:2023-11-30 21:59:20 25 4
gpt4 key购买 nike

如何为命名空间创建树状数据结构。

例如,对于这些命名空间:

Enums.NEWENUMS.NEW1
Enums.NEWENUMS.NEW2
Enums.NEWENUMS.NEW3
Enums.OLDENUMS
Enums.TEST.SUB
Enums.TEST.SUB.OK

然后将其加载到 TreeView 中,如下所示:

enter image description here

我尝试拆分 namespace ,但我终究想不出正确生成它的逻辑。

还尝试按照您生成目录结构的方式生成它,但由于命名空间需要拆分,所以我无法理解它。

最佳答案

1。解析命名空间

这是代表命名空间的类。它将命名空间表示为直接嵌套命名空间的字典。为了从字符串生成 Namespace,它提供了使用 recursive calls 的静态方法。和 LINQ :

public class Namespace : IDictionary<String, Namespace>
{
#region Static

public static IEnumerable<Namespace> FromStrings(IEnumerable<String> namespaceStrings)
{
// Split all strings
var splitSubNamespaces = namespaceStrings
.Select(fullNamespace =>
fullNamespace.Split('.'));

return FromSplitStrings(null, splitSubNamespaces);
}

public static IEnumerable<Namespace> FromSplitStrings(Namespace root, IEnumerable<IEnumerable<String>> splitSubNamespaces)
{
if (splitSubNamespaces == null)
throw new ArgumentNullException("splitSubNamespaces");

return splitSubNamespaces
// Remove those split sequences that have no elements
.Where(splitSubNamespace =>
splitSubNamespace.Any())
// Group by the outermost namespace
.GroupBy(splitNamespace =>
splitNamespace.First())
// Create Namespace for each group and prepare sequences that represent nested namespaces
.Select(group =>
new
{
Root = new Namespace(group.Key, root),
SplitSubnamespaces = group
.Select(splitNamespace =>
splitNamespace.Skip(1))
})
// Select nested namespaces with recursive split call
.Select(obj =>
new
{
Root = obj.Root,
SubNamespaces = FromSplitStrings(obj.Root, obj.SplitSubnamespaces)
})
// Select only uppermost level namespaces to return
.Select(obj =>
obj.Root)
// To avoid deferred execution problems when recursive function may not be able to create nested namespaces
.ToArray();
}

#endregion



#region Fields

private IDictionary<String, Namespace> subNamespaces;

#endregion


#region Constructors

private Namespace(String nameOnLevel, Namespace parent)
{
if (String.IsNullOrWhiteSpace(nameOnLevel))
throw new ArgumentException("nameOfLevel");

this.Parent = parent;
this.NameOnLevel = nameOnLevel;
this.subNamespaces = new Dictionary<String, Namespace>();

if (this.Parent != null)
{
this.Parent.Add(this.NameOnLevel, this);
}
}

private Namespace(String nameOfLevel)
: this(nameOfLevel, null)
{

}

#endregion


#region Properties

public String NameOnLevel
{
get;
private set;
}

public String FullName
{
get
{
if (this.Parent == null)
return this.NameOnLevel;

return String.Format("{0}.{1}",
this.Parent.FullName,
this.NameOnLevel);
}
}

private Namespace _Parent;

public Namespace Parent
{
get
{
return this._Parent;
}
private set
{
if (this.Parent != null)
this.Parent.Remove(this.NameOnLevel);

this._Parent = value;
}
}

#endregion



#region IDictionary implementation

public void Add(string key, Namespace value)
{
if (this.ContainsKey(key))
throw new InvalidOperationException("Namespace already contains namespace with such name on level");

this.subNamespaces.Add(key, value);
}

public bool ContainsKey(string key)
{
return this.subNamespaces.ContainsKey(key);
}

public ICollection<string> Keys
{
get { return this.subNamespaces.Keys; }
}

public bool Remove(string key)
{
if (!this.ContainsKey(key))
throw new KeyNotFoundException();

this[key]._Parent = null;

return this.subNamespaces.Remove(key);
}

public bool TryGetValue(string key, out Namespace value)
{
return this.subNamespaces.TryGetValue(key, out value);
}

public ICollection<Namespace> Values
{
get { return this.subNamespaces.Values; }
}

public ICollection<Namespace> Subnamespaces
{
get { return this.subNamespaces.Values; }
}

public Namespace this[string nameOnLevel]
{
get
{
return this.subNamespaces[nameOnLevel];
}
set
{
if (value == null)
throw new ArgumentException("value");

Namespace toReplace;

if (this.TryGetValue(nameOnLevel, out toReplace))
{
toReplace.Parent = null;
}

value.Parent = this;
}
}

public void Add(KeyValuePair<string, Namespace> item)
{
this.Add(item.Key, item.Value);
}

public void Clear()
{
foreach (var subNamespace in this.subNamespaces.Select(kv => kv.Value))
{
subNamespace._Parent = null;
}

this.subNamespaces.Clear();
}

public bool Contains(KeyValuePair<string, Namespace> item)
{
return this.subNamespaces.Contains(item);
}

public void CopyTo(KeyValuePair<string, Namespace>[] array, int arrayIndex)
{
this.subNamespaces.CopyTo(array, arrayIndex);
}

public int Count
{
get { return this.subNamespaces.Count; }
}

public bool IsReadOnly
{
get { return false; }
}

public bool Remove(KeyValuePair<string, Namespace> item)
{
return this.subNamespaces.Remove(item);
}

public IEnumerator<KeyValuePair<string, Namespace>> GetEnumerator()
{
return this.subNamespaces.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion



#region Overrides

public override string ToString()
{
return this.FullName;
}

#endregion
}

附注:此类可能有一些未正确实现的方法。

P.S.1:无需 LINQ 即可重写解析方法。事实上,这个 LINQ 解决方案不是很地道,也不是一个很好的例子来说明如何以及何时使用 LINQ。但它很短,而且大多很简单。

2。将命名空间添加到 TreeView

您没有提到您使用的 UI 框架,所以我默认使用 Windows 窗体。假设您已将名为 treeView_Namespaces 的 TreeView 添加到表单中:

public Form1()
{
InitializeComponent();

var namespaceStrings = new String[]
{
"Enums.NEWENUMS.NEW1",
"Enums.NEWENUMS.NEW2",
"Enums.NEWENUMS.NEW3",
"Enums.OLDENUMS",
"Enums.TEST.SUB",
"Enums.TEST.SUB.OK"
};

var namespaces = Namespace.FromStrings(namespaceStrings);

AddNamespaces(this.treeView_Namespaces.Nodes, namespaces);
}

void AddNamespaces(TreeNodeCollection nodeCollection, IEnumerable<Namespace> namespaces)
{
foreach (var aNamespace in namespaces)
{
TreeNode node = new TreeNode(aNamespace.NameOnLevel);
nodeCollection.Add(node);

AddNamespaces(node.Nodes, aNamespace.Subnamespaces);
node.Expand();
}
}

3。如果你需要从真实的命名空间生成这样的树

为此,您必须遍历 Assembly 中的类型并获取它们所有的命名空间:

例如,此代码获取当前正在执行的程序集中的所有类型:

var namespaceStrings = Assembly
.GetExecutingAssembly()
.GetTypes()
.Select(type =>
type.Namespace)
.Where(@namespace =>
@namespace != null);

关于c# - 如何从字符串表示形式创建表示 namespace 的树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29320175/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com