C # Data Structures question (which collection to use?)

I need to implement a large collection of Widget objects, each of which contains a unique file path string ("FilePath"). I need to do the following:

  • Get the Widget object quickly by specifying the file path
  • Change the path to the widget file without creating a new object (several other objects may contain links to one widget, and their tracking will affect performance)
  • Given the Widget link, determine the file path

At first I thought about using a common SortedList, using the file path as the key, but duplicating the path for many thousands of objects can quickly eat up memory. I decided to remove the path from the object and save it only in the list of keys, but this would make it difficult to fulfill requirement 3.

Now I tend to collapse my own class, obtained from List <>, which adds Widget objects in sorted order and retrieves them using binary search. Requirement 2 can be fulfilled simply by removing an object from the list, changing its path to the file and adding it to the list.

But I'm relatively new to C #, and I wanted to check with great minds here and see if I was missing another obvious solution.

Thanks!

+3
source share
6 answers

"" : #, ( , 4 8 ) :

Dictionary<string, Widget> dict = new Dictionary<string, Widget>();
Widget myWidget = GetSomeWidget();
dict.Add(myWidget.Name, myWidget);

, dict .

, SortedList, , (O log n) // O (n) )

, , .

: ( ) , , , , (?) ...

+4

2 ?

Dictionary<string, Widget> WidgetsByPath;
Dictionary<Widget, string> PathsByWidget;

( , ), , , , .

:

public class Widgets
{
  public Widget Add(string Path, Widget wdg)
  {
    // Chek it doesn't already exits and all...
    WidgetsByPath.Add(Path, wdg);
    PathsByWidget.Add(wdg, Path);
  }

  public void Delete(string Path)
  {
    Widget w = WidgetsByPath[Path];
    PathsByWidget.Delete(w);
    WidgetsByPath.Delete(Path);
  }
}
+9

" "? , ? .

+4

, , . . , , , .

+2

, <Widget> Widget, . , Widget FilePath.

 public class WidgetDictionary : Dictionary<string,Widget>
 {
     ... provide suitable constructors ...

     public void Add( Widget widget )
     {
         if (widget != null && !this.ContainsKey( widget.FilePath ))
         {
             this.Add( widget.FilePath, widget );
         }
     }
 }

 public class Widget
 {
      public string FilePath { get; set; }

      private List<Widget> widgets = new List<Widget>();
      public IEnumerable<Widget> Widgets
      {
          get { return widgets; }
      }

      ...code to add/remove widgets from list...
 }

, (1), .

 var repository = new WidgetDictionary();
 string filePath = ...
 var widget = repository[filePath];

(2), . , , - .

var widget = repository[filePath];
repository.Remove(filePath);
widget.FilePath = newFilePath;
repository.Add(widget);

 EDIT: this could probably be implemented as a method on the
 dictionary as well.

   public void UpdatePath( Widget widget, string newPath )
   {
       if (string.IsNullOrEmpty(newPath))
          throw new ArgumentNullException( "newPath" );

       var widget = this.ContainsKey(widget.FilePath)
                             ? this[widget.FilePath]
                             : null;

       if (widget != null)
       {           
           this.Remove(widget.FilePath);
       }
       widget.FilePath = newPath;
       this.Add( widget );
    }

(3) .

var filePath = widget.FilePath;

, , (), , , , Widget IDisposable dispose, , , . . MSDN , .

+2

Do you consider using a class Path? Internally, a path is a string, and there are excellent methods for getting various parts of a path, i.e. GetFullPath, GetFileNameetc.

0
source

Source: https://habr.com/ru/post/1706276/


All Articles