.NET:用于字符串键的切换与字典

时间:2009-08-26 11:34:18

标签: .net dictionary switch-statement

我遇到的情况是我有一个业务对象,其中包含大约15种不同类型的属性。业务对象还必须实现具有以下方法的接口:

object GetFieldValue(string FieldName);

我可以看到实现此方法的两种方法:

使用switch语句:

switch ( FieldName )
{
    case "Field1": return this.Field1;
    case "Field2": return this.Field2;
    // etc.
}

使用字典(SortedDictionary或HashTable?):

return this.AllFields[FieldName];

哪个更有效率?

已添加:忘了说。此方法用于在网格中显示项目。网格将为每个属性都有一列。通常会有超过1000个项目的网格。这就是我担心表现的原因。

已添加2:

这是一个想法:混合方法。创建一个静态字典,其中键是属性名称,值是数组中的索引。在应用程序启动时,字典仅填充一次。每个对象实例都有一个数组。所以,查找就像:

return this.ValueArray[StaticDictionary[FieldName]];

字典填充算法可以使用反射。然后将相应地实现属性本身:

public bool Field1
{
    get
    {
        object o = this.ValueArray[StaticDictionary["Field1"]]; 
        return o == null ? false : (bool)o;
    }
    set
    {
        this.ValueArray[StaticDictionary["Field1"]] = value;
    }
}

任何人都可以看到有任何问题吗?

它还可以更进一步,ValueArray / StaticDictionary可以放在一个单独的泛型类型ValueCollection<T>中,其中T将指定反射的类型。 ValueCollection还将处理尚未设置任何值的情况。然后可以将属性简单地写为:

public bool Field1
{
    get
    {
        return (bool)this.Values["Field1"];
    }
    set
    {
        this.Values["Field1"] = value;
    }
}

最后,我开始怀疑,如果一个简单的switch语句可能不会更快更容易维护....

4 个答案:

答案 0 :(得分:21)

switch:      good efficiency, least maintainable
dictionary:  good efficiency, better maintainability
reflection:  least efficient, best maintainability

提示:忽略效率并仅担心可维护性,除非您实际测试了性能并发现它是一个问题。

我不是说反射是你唯一的选择,只是它允许你根据需要添加/删除和重命名属性,而不需要保持switch语句或字典同步。

答案 1 :(得分:7)

因为你正在使用字符串字典可能会更快。在使用字符串时,Switch基本上会转换为哈希表。但是如果你使用整数或类似的东西,它会被转换为跳转表并且会更快。

请参阅this answer并提问以了解更多详情

最好的办法是对其进行分析并确定

答案 2 :(得分:0)

如何获得每个属性的值可能对整体性能的影响小于渲染网格的方式。

我举个例子: 假设你有以下实现:

private string _latestFieldName = string.Empty;
private PropertyInfo _propertyInfo;

object GetFieldValue(string FieldName)
{
  if(FieldName != _latestFieldName)
  {
    _propertyInfo = typeof(yourTypeName).GetProperty(FieldName);
  }
  return _propertyInfo.GetValue(this,null);
}

如果您的网格渲染使用反射一次渲染一行,则必须每次都获取propertyinfo。 如果你逐列渲染你只需要为每个属性获取一次propertyInfo,并且因为分支预测几乎每次你只错过if上的几个时钟周期。如果已经拥有PropertyInfo,则无需将调用结果转换为GetValue。在速度方面,使用反射非常接近使用属性的吸气剂。

我的观点是在您开始优化使用分析器之前。 (当然,如果你不能很好地改变网格,你也无法真正优化它)

答案 3 :(得分:0)

与字典相比,Switch实际上有两个好处:

  1. 您可以在默认部分创建可包含无效值的自定义异常消息。在字典的情况下,你只得到没有包含密钥名称的KeyNotFoundException。
  2. 您可以处理空值。字典不能将null存储为密钥。