c# - How to create a tree representing namespaces from their string representations -


how can create tree-like data structure namespaces.

for example, these namespaces:

enums.newenums.new1 enums.newenums.new2 enums.newenums.new3 enums.oldenums enums.test.sub enums.test.sub.ok 

and load treeview shown below:

enter image description here

i tried split namespaces, life of me can't think of logic generate correctly.

also tried generate way generate directory structure, can't head around since namespaces need splitting.

1. parsing namespace

here class represents namespace. represents namespace dictionary of directly nested namespaces. generate namespaces strings provides static methods use recursive calls , linq:

public class namespace : idictionary<string, namespace> {     #region static      public static ienumerable<namespace> fromstrings(ienumerable<string> namespacestrings)     {         // split 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 split sequences have no elements             .where(splitsubnamespace =>                 splitsubnamespace.any())             // group outermost namespace             .groupby(splitnamespace =>                  splitnamespace.first())             // create namespace each group , prepare sequences represent nested namespaces             .select(group =>                 new                 {                     root = new namespace(group.key, root),                     splitsubnamespaces = group                         .select(splitnamespace =>                             splitnamespace.skip(1))                 })             // select nested namespaces recursive split call             .select(obj =>                 new                 {                     root = obj.root,                     subnamespaces = fromsplitstrings(obj.root, obj.splitsubnamespaces)                 })             // select uppermost level namespaces return             .select(obj =>                 obj.root)             // avoid deferred execution problems when recursive function may not able 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     {                 {             if (this.parent == null)                 return this.nameonlevel;              return string.format("{0}.{1}",                 this.parent.fullname,                 this.nameonlevel);         }     }      private namespace _parent;      public namespace parent     {                 {             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 contains namespace such name on level");          this.subnamespaces.add(key, value);     }      public bool containskey(string key)     {         return this.subnamespaces.containskey(key);     }      public icollection<string> keys     {         { 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     {         { return this.subnamespaces.values; }     }      public icollection<namespace> subnamespaces     {         { return this.subnamespaces.values; }     }      public namespace this[string nameonlevel]     {                 {             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     {         { return this.subnamespaces.count; }     }      public bool isreadonly     {         { 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: class may have few incorrectly implemented methods.

p.s.1: parsing methods can rewritten without linq. linq solution not idiomatic or example of how , when use linq. short , simple.

2. adding namespaces treeview

you haven't mentioned ui framework use, have defaulted windows forms. assuming have added treeview named treeview_namespaces form:

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. if need generate such tree real namespaces

to have walk through types in assembly , namespaces:

for example, code types in executing assembly:

var namespacestrings = assembly     .getexecutingassembly()     .gettypes()     .select(type =>         type.namespace)     .where(@namespace =>         @namespace != null); 

Comments

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -