1

Novice question. What collection type should I use to store such structure?

Files collection
---------------
FileId: Int
FileName : String
Path: String

I will need to store several files data into that collection, find Path by FileId field, delete item by FileId field.

Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
Tomas
  • 17,551
  • 43
  • 152
  • 257

4 Answers4

8

I would create a Dictionary with a custom class as value:

public class FileInfo
{
    public string FileName {get;set;}
    public string Path {get;set;}
}

and store in a Dictionary<int, FileInfo> dictionary where you keep FileId as key in the Dictionary.

Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108
6

Since you have several pre-defined pieces of information that you want associated with each value instance, I would start by defining a structure to hold the information required for each file:

public struct CustomFileInfo  //pick a name that avoids conflicts with System.IO
{
    public readonly int FileId;
    public readonly string FileName;
    public readonly string Path;

    // constructor
    public CustomFileInfo(int fileId, string fileName, string path)
    {
        this.FileId = fileId;
        this.FileName = fileName;
        this.Path = path;
    }
}

And then I would use a generic collection (such as a List<T>) to hold instances of that structure:

List<FileInfo> myFiles = new List<FileInfo>();

Alternatively, you could use a Dictionary<TKey, TValue>, with the FileId as the key and the FileInfo structure as the value. For example:

Dictionary<int, FileInfo> myFiles = new Dictionary<int, FileInfo>();

The advantage of a dictionary is that it provides faster lookup time when searching for a file by its ID. This is because a dictionary is implemented internally using a hash table.

EDIT: Note that mutable structs are evil. If you need to be able to change the individual pieces of information that describe a file (and I can't imagine why you would), you should declare CustomFileInfo as a class instead of a struct.

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • `Dictionary` is a better solution for searching than `List`. – acoolaum Mar 28 '11 at 10:30
  • @acoo: Indeed, if you were planning on doing a lot of searching. As best I can tell from the question, the asker only wants a way to store a collection of this information. – Cody Gray - on strike Mar 28 '11 at 10:31
  • +1 for suggesting a struct, the data structure described by the op is a good candidate – MattDavey Mar 28 '11 at 10:36
  • @Cody Gray, `Dictionary` isn't only fast search & good storage, additionaly it provide methods to control keys (IDs) and work with them. – acoolaum Mar 28 '11 at 10:36
  • @acoo: What methods did you have in mind that the `Dictionary` collection provides that the `List` doesn't? – Cody Gray - on strike Mar 28 '11 at 10:38
  • How to add new structure to the list? I have tried code below but that does not work myFiles.Add(new FileInfo(fileId, fileName, uploadFileName)); – Tomas Mar 28 '11 at 10:42
  • @Tomas: Presumably, that isn't working because there is no constructor defined for the `FileInfo` structure. You'd either need to add that, or create the `FileInfo` instance outside of the call to the `Add` method. I'll update my answer with a constructor. – Cody Gray - on strike Mar 28 '11 at 10:44
  • Just watch out for problems related to mutable value types. – Fredrik Mörk Mar 28 '11 at 10:47
  • @Fredrik: Hmm, in my mind, I had actually conceived of these objects as being immutable. That's why I chose to represent them as a structure in the first place. I didn't really intend to write a complete solution to the problem, just provide some ideas to help get the asker started in the right direction, but it looks like I've just about abandoned that altogether. They probably should be declared as `readonly`. – Cody Gray - on strike Mar 28 '11 at 10:54
  • @Cody: yes, making them `readonly` is definitely a good idea. – Fredrik Mörk Mar 28 '11 at 10:56
  • Cody could you show how to search for specified FileId in the list and read values of that record and after that delete that records from the list? I have tried to look for myFiles.Find method information and do not understand how to use it. Seems very complex. – Tomas Mar 28 '11 at 11:07
  • @Tomas: Yeah, you need to understand delegates. The [documentation](http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx) actually has a pretty good sample implementation already. See if that helps you out any. – Cody Gray - on strike Mar 28 '11 at 11:21
3

There are several approaches possible.

Assuming a structure like this:

  class File
  {
    int FileId { get; set; }
    string FileName { get; set; }
    string Path { get; set; }
  }

Simple generic list
You can hold your data in a simple generic list:

List<File> File { get; set; }

Observable collection
If you need to bind the collection to a WPF UI and its content is update from somewhere in your code, I suggest:

ObservableCollection<File> Files { get; set; }

Dictionary
If FileId is unique and it is the only property you use to find the items, you can put them into a dictionary like this:

Dictionary<int, File> File { get; set; }
Markus
  • 4,487
  • 3
  • 41
  • 51
2

Create a File class:

public class File
{
    public int Id { get; private set; }
    public string Path { get; private set; }
    public string FileName
    {
        get
        {
            return System.IO.Path.GetFileName(this.Path);
        }
    }
    public File(int id, string path)
    {
        this.Id = id;
        this.Path = path;
    }
}

Then, you can either store the objects in a List<File>:

List<File> files = GetFiles();
files.RemoveAll(f => f.Id == 42);

..or in a Dictionary<int, File>:

Dictionary<int, File> files = GetFiles(); // GetFiles should use File.Id as key
files.Remove(42);

The upside with the Dictionary is that you have extremely efficient lookup on the key. The upside with the List is that you have flexibility and can easily write code to remove based on any value of the contained File objects, such as:

files.RemoveAll(f => f.Path.Contains("stuff"));
Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
  • Agreed, except that I wouldn't call the class `File` since that conflicts with the class defined in `System.IO`. You're very likely to have that namespace imported at the same time you're using this class. – Cody Gray - on strike Mar 28 '11 at 10:32
  • 1
    @Cody: yes, the naming can be improved upon. There is already a conflict *inside* the `File` type between the property `Path` and `System.IO.Path` (hence the use of the fully qualified name). On a side note; `FileInfo` will also create a conflict ;-) – Fredrik Mörk Mar 28 '11 at 10:34