Using a List, Lookup or Dictionary for a large list of data

c#, dictionary, list, lookup

Solution

For a more thorough assessment, you might want to consider codereview.SE.

Some general notes on `List<T>` vs `Dictionary<TKey, TValue>` vs `Lookup<TKey, TElement>`

As other answers have shown, using a List is terrible in your scenario, mainly because looking up elements will have bad performance.

Choosing between `Dictionary` and `Lookup` isn't hard (from MSDN, emphasis mine):

A `Lookup<TKey, TElement>` resembles a `Dictionary<TKey, TValue>.` The difference is that a `Dictionary<TKey, TValue>` maps keys to single values, whereas a `Lookup<TKey, TElement>` maps keys to collections of values.

You can create an instance of a `Lookup<TKey, TElement>` by calling `ToLookup` on an object that implements `IEnumerable<T>.`

Since you will only need to map keys to single values, a `Dictionary` is the right choice.

The previously accepted answer is a step in the right direction but still gets several key things wrong (edit: these problems have since been resolved).

Strings are immutable: `s.Trim()` will not change `s` — it will return a new `string` meaning you need to `s = s.Trim()` if you are using to `s` afterwards, which you are.

A static class can't have an instance constructor: `public Lookups()` should be `static Lookups()` (static constructors are not allowed to have access modifiers — of course).

Don't return an empty string / an error message as a string!

That's going to end up as a wonderful debugging headache. You should be using Exceptions instead of passing error strings around — and you should provide a `VersionExists` method to check if your dictionary contains a certain version!

Modified, safer example

This will throw a `FormatException` if the parameter is empty, null or whitespace. In the event that the version doesn't exist, the `Dictionary` will throw a `KeyNotFoundException` — a bit more helpful for debugging than `string.Empty`, don't you think?

public static class Lookups
{
    private static Dictionary<string, Vers> Versions;

    static Lookups()
    {
        Versions = new Dictionary<string, Vers>
        {
            {"0000", new Vers {VersionNumber = "0000", VersionLiteral = "Location 1"}},
            {"0001", new Vers {VersionNumber = "0001", VersionLiteral = "Location 2"}},
            {"0002", new Vers {VersionNumber = "0002", VersionLiteral = "Location 3"}},
            {"0003", new Vers {VersionNumber = "0003", VersionLiteral = "Location 4"}},
            {"0004", new Vers {VersionNumber = "0004", VersionLiteral = "Location 5"}},
            {"0005", new Vers {VersionNumber = "0005", VersionLiteral = "Location 6"}},
            {"0006", new Vers {VersionNumber = "0006", VersionLiteral = "Location 7"}},
            {"0007", new Vers {VersionNumber = "0007", VersionLiteral = "Location 8"}}
        };
    }

    public static bool VersionExists(string versionNumber)
    {
        return Versions.ContainsKey(versionNumber);
    }

    public static string GetVersion(string s)
    {
        if (string.IsNullOrWhiteSpace(s)) 
            throw new FormatException("Empty version number!");
        return Versions[s.Trim()].VersionLiteral;
    }
}

Problem

I have a static class in my Class Library called Lookup, I am using this class to look up different values (in this case Locations). These values can number into the hundreds. Since 95% of my customers install my app on a machine without Internet access I have to assume that my applications will not have internet access nor access to a database. So I want to know if this is an efficient way of handling this and if I am properly disposing the object when the method is done: CODE : ``` using System; using System.Collections.Generic; namespace FunctionLibrary { public static class Lookups { private static List<Vers> Versions; public static string GetVersion(string s) { string retValue = string.Empty; Versions = new List<Vers>(); try { if (s.Trim().Length > 0) { GetVersions(); retValue = Versions.Find(ver => ver.VersionNumber == s).VersionLiteral; if (string.IsNullOrEmpty(retValue)) { retValue = string.Format("{0} is an Unknown Version Number", s); } } else { retValue = "No version number supplied"; } } catch { retValue = string.Format("{0} is an Unknown Version Number", s); } finally { Versions.Clear(); Versions = null; } return retValue; } private static void GetVersions() { Versions.Add(new Vers() { VersionNumber = "0000", VersionLiteral = "Location 1" }); Versions.Add(new Vers() { VersionNumber = "0001", VersionLiteral = "Location 2" }); Versions.Add(new Vers() { VersionNumber = "0002", VersionLiteral = "Location 3"}); Versions.Add(new Vers() { VersionNumber = "0003", VersionLiteral = "Location 4"}); Versions.Add(new Vers() { VersionNumber = "0004", VersionLiteral = "Location 5"}); Versions.Add(new Vers() { VersionNumber = "0005", VersionLiteral = "Location 6"}); Versions.Add(new Vers() { VersionNumber = "0006", VersionLiteral = "Location 7"}); Versions.Add(new Vers() { VersionNumber = "0007", VersionLiteral = "Location 8"}); } } public class Vers { public string VersionLiteral { get; set; } public string VersionNumber { get; set; } } } ``` I am also wondering if I should use a Dictionary or a Lookup instead of the list. I just don't want multiple calls to this method to cause memory issues.

Original source