使用List,Lookup或Dictionary来获取大量数据

时间:2012-07-22 06:18:15

标签: c# list dictionary lookup

我的类库中有一个名为Lookup的静态类,我使用此类来查找不同的值(在本例中为Locations)。

这些值可以达到数百。由于95%的客户在没有Internet访问权限的计算机上安装我的应用程序,因此我必须假设我的应用程序无法访问Internet或访问数据库。

所以我想知道这是否是一种有效的处理方法,如果我在方法完成后正确处理对象:

代码:

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; }
   }
}

我也想知道是否应该使用Dictionary或Lookup而不是列表。我只是不希望多次调用此方法导致内存问题。

3 个答案:

答案 0 :(得分:16)

要进行更全面的评估,您可能需要考虑codereview.SE


List<T>Dictionary<TKey, TValue> vs Lookup<TKey, TElement>

上的一些常规说明

正如其他答案所示,在你的场景中使用List很糟糕,主要是因为查找元素会有不好的表现。

DictionaryLookup之间选择并不难(来自MSDN,强调我的):

  

Lookup<TKey, TElement>类似于Dictionary<TKey, TValue>.,区别在于   Dictionary<TKey, TValue>将键映射到单个值,而a   Lookup<TKey, TElement>将键映射到值集合

     

您可以致电Lookup<TKey, TElement>来创建ToLookup的实例   在实现IEnumerable<T>.

的对象上

由于您只需要将键映射到单个值,因此Dictionary是正确的选择。


previously accepted answer是向正确方向迈出的一步,但仍然会出现几个关键错误(编辑:这些问题已经解决)

字符串是不可变的: s.Trim()不会更改s - 它会返回一个新的string,这意味着如果你是s = s.Trim()则需要s之后使用public Lookups()

静态类不能有实例构造函数static Lookups()应该是VersionExists(当然,静态构造函数不允许有访问修饰符)。

不要将空字符串/错误消息作为字符串返回!

这将成为一个精彩的调试头痛。你应该使用 Exceptions 而不是传递错误字符串 - 你应该提供FormatException方法来检查你的字典是否包含某个版本!

修改后的更安全的例子

如果参数为空,null或空格,则抛出Dictionary。如果该版本不存在,KeyNotFoundException会抛出string.Empty - 比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; } } 更有助于调试,你不觉得吗?

{{1}}

答案 1 :(得分:3)

试试:

using System;
using System.Collections.Generic;

namespace FunctionLibrary
{
public static class Lookups
{
    private static Dictionary<string, Vers> Versions = new Dictionary<string, Vers>();

    static Lookups() //Static constructor
    {
        CreateVesions();
    }

    public static string GetVersion(string s)
    {
        string retValue = string.Empty;

                    s = s.Trim();

        if (s.Length > 0 && Versions.ContainsKey(s))
        {
            retValue = Versions[s].VersionLiteral;
        }

        if (string.IsNullOrEmpty(retValue))
        {
            retValue = string.Format("{0} is an Unknown Version Number", s);
        }

        return retValue;
    }

    private static void CreateVesions()
    {
        Versions["0000"] = new Vers() { VersionNumber = "0000", VersionLiteral = "Location 1" };
        Versions["0001"] = new Vers() { VersionNumber = "0001", VersionLiteral = "Location 2" };
        Versions["0002"] = new Vers() { VersionNumber = "0002", VersionLiteral = "Location 3" };
        Versions["0003"] = new Vers() { VersionNumber = "0003", VersionLiteral = "Location 4" };
        Versions["0004"] = new Vers() { VersionNumber = "0004", VersionLiteral = "Location 5" };
        Versions["0005"] = new Vers() { VersionNumber = "0005", VersionLiteral = "Location 6" };
        Versions["0006"] = new Vers() { VersionNumber = "0006", VersionLiteral = "Location 7" };
        Versions["0007"] = new Vers() { VersionNumber = "0007", VersionLiteral = "Location 8" };
    }
}

public class Vers
{

    public string VersionLiteral { get; set; }
    public string VersionNumber { get; set; }
}

}

你得到:

  1. 仅初始化值
  2. 使用词典查找版本的性能更佳
  3. GetVersion方法
  4. 中的代码较少

答案 2 :(得分:2)

在这种情况下使用List会导致巨大的低效率。在这种情况下,你的申请将会非常缓慢。

查找词典会有所帮助。

它们之间的区别在于,当Dictionary只接受一个时,Lookup允许您为给定的键提供多个值。

因此,如果在您的情况下VersionNumber是唯一的,则使用Dictionary,否则使用Lookup。

您只需将列表转换为字典或查找一次:

var versionsDictionary = versionsList
                             .ToDictionary(x => x.VersionNumber);

所以你做了一次(也许当你的应用程序加载时),然后在任何地方使用它:

var myVersion = versionsDictionary[givenNumber];
Console.WriteLine(myVersion.VersionLiteral);

同样,如果你需要Lookup,那么用ToLookup替换ToDictionary;)