.NET字典与类属性

时间:2012-01-13 01:36:55

标签: c# javascript collections

来自javascript背景,像词典这样的集合通常被实现为对象,因为它们的属性可以通过关联引用:

// Javascript example
var myDictionary = {
  namevalue1 : "value1",
  namevalue2 : "value2"
};

console.log( myDictionary.namevalue1 );    // "value1"
console.log( myDictionary["namevalue1"] ); // "value1"

我正在编写C#,我想知道为查找存储字符串值的正确方法是在单例类还是在通用字典中。我喜欢类强类型并提供intellisense支持,但我预计会有很多更改并维护类属性而不是简单地调用Dictionary方法似乎很头疼。性能优势是否如此之大,我应该选择其中一个?

8 个答案:

答案 0 :(得分:7)

实际上,一个类比Dictionary快几个数量级。如果你觉得它更方便,那就更好:)所以如果你能够为它制作课程,那就去做吧。如果你所代表的对象应该是类(即基本上是对象而不是键/值对),那么就更有理由了。

答案 1 :(得分:4)

您的javascript示例与字典以及:

不对应
var myDictionary = [];
myDictionary["namevalue1"] = "value1";
myDictionary["namevalue2"] = "value2";

现在,我们可以使用我们可以用你的代码完成所有工作,但它并不是真正建模相同的东西。您的定义属性,而我将值与键关联。你已经在语义上创建了一个结构化的对象,我已经创建了一个更平坦的对象,虽然在我不知道我将用什么字符串作为键的情况下我更灵活一点(在js中没有那么多,因为js的运行时灵活性意味着如果密钥是有效标签,动态添加新属性并不太难。

就像在Javascript中一样,在C#中:

如果你有一小部分在编译时已知的属性,那么具有这些属性的类最接近你的意图模型。

如果您有大量属性或在编译时不了解它们,那么字典将最接近您的意图模型。

这两种情况下这些可能是性能最高的这一事实只是一个额外的好处,可以在语言允许的情况下尽可能地模拟你的意图,如果绝对必要的话,可以考虑逐步退出。

与JS没什么不同,除了它对你一次做的事情有点严格(如果我们真的需要,我们可以绕过那么严格,但是你呢?)。

答案 2 :(得分:1)

C# Dictionary class使用泛型强类型化。您可以在使用时指定键的类型和值。

我建议您学习字典类,因为您很可能会发现它对许多用途都有用。

如果不了解更多关于您的用例的话,很难进一步评论,但总的来说,在您知道它是一个问题之前我不会担心Dictionary类的性能,如果它是,那么稍后重构。 (我勇敢地预测它不会)。

答案 3 :(得分:1)

如果你想在javascript中进行那种鸭子打字,但是在C#中你可以使用ExpandoObject。这是一个.Net 4类。您可以动态设置其属性,如:

dynamic myObject = new ExpandoObject();
myObject.namevalue1 = "value1";
myObject.namevalue2 = "value2";

与ExpandoObject相关的一个很好的技巧是,您可以使用与访问字典值相同的方式访问ExpandoObject上的属性:

var myDictionary = myObject as IDictionary<string, object>;
Console.WriteLine(myDictionary["namevalue1"]); // value1
Console.WriteLine(myDictionary["namevalue2"]); // value2

请记住您将从动态语言( javascript )变为静态语言( C#),标准和范例是非常不同。创建一个表示数据模型的类会比使用的动态对象更快更快,更好。

答案 4 :(得分:1)

这实际上取决于您的使用案例。 C#词典比您通常期望的JavaScript代码更高效。另外,正如The Don指出的那样,“我们应该忘记小的效率,比如大约97%的时间;过早的优化是所有邪恶的根源”。我提供了几个提供与示例JavaScript相同的输出的示例:

enum DictKeys
{
    nameValue1,
    nameValue2,
}

void Main()
{
    var myDictionary = new Dictionary<string, string>();
    myDictionary.Add("namevalue1", "value1");
    myDictionary.Add("namevalue2", "value2");

    Console.WriteLine(myDictionary["namevalue1"]); // "value1"

    var myDict2 = new Dictionary<DictKeys, string>();
    myDict2.Add(DictKeys.nameValue1, "value1");
    myDict2.Add(DictKeys.nameValue2, "value2");

    Console.WriteLine(myDict2[DictKeys.nameValue1]); // "value1"
}

答案 5 :(得分:1)

类比字典快得多。但是,字典仍然非常快。这是一个 .NET Fiddle 比较它们的性能:https://dotnetfiddle.net/NbFw4s

结果:

Dictionary read:  24,544,154 ops/sec
Object read:     383,327,796 ops/sec
-------------------------------------------
Dictionary write: 22,017,208 ops/sec
Object write:    228,458,287 ops/sec

如您所见,类比字典快一个数量级。然而,以每秒 24 百万 次操作,除了对性能最敏感的应用程序之外,Dictionaries 仍然完全可以接受(即使那样,我也会怀疑 Dictionaries性能问题的根源)。

来自 dotnetfiddle 的代码:

using System;
using System.Diagnostics;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Stopwatch stopwatch;
        var operations = 15000000;
        var dict = new Dictionary<string, string>() {{"Name", "Bob"}};
        var obj = new Person { Name = "Bob" };

        stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < operations; i++)
        {
            var firstName = dict["Name"];
        }
        stopwatch.Stop();
        Console.WriteLine("Dictionary read: " + (operations / stopwatch.Elapsed.TotalSeconds).ToString("N0") + " ops/sec");
        
        stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < operations; i++)
        {
            var firstName = obj.Name;
        }
        stopwatch.Stop();
        Console.WriteLine("Object read:    " + (operations / stopwatch.Elapsed.TotalSeconds).ToString("N0") + " ops/sec");
        
        Console.WriteLine("-------------------------------------------");
        
        stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < operations; i++)
        {
            dict["Name"] = "Jim";
        }
        stopwatch.Stop();
        Console.WriteLine("Dictionary write: " + (operations / stopwatch.Elapsed.TotalSeconds).ToString("N0") + " ops/sec");
        
        stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < operations; i++)
        {
            obj.Name = "Jim";
        }
        stopwatch.Stop();
        Console.WriteLine("Object write:    " + (operations / stopwatch.Elapsed.TotalSeconds).ToString("N0") + " ops/sec");
        
    }
    
    class Person {
        public string Name;
    }
}

答案 6 :(得分:0)

具有属性的类将为您提供性能提升和智能感知支持。另一方面,如果需要,字典可以为您提供更大的灵活性。

答案 7 :(得分:0)

因为你将它用于数据....一个“DataTable”,这是一个微软的抽象,基本上是一个大词典。您可能想要调查DataTable,因为它有很多附带的玩具可以让您的生活更轻松。