【问题标题】:What collection object is appropriate for fixed ordering of values?什么集合对象适合固定的值排序?
【发布时间】:2011-01-17 19:10:15
【问题描述】:

场景:我正在跟踪几个性能计数器,并且有一个与 DataSnapshot[] 相关的 CounterDescription[]... 其中 CounterDescription[n] 描述了 DataSnapshot[n] 中加载的数据。

我想在 C# 中公开一个易于使用的 API,以便轻松高效地扩展数组。

简化示例(变得更复杂)

CounterDescription[0] = Humidity;
DataSnapshot[0] = .9;
CounterDescription[1] = Temp;
DataSnapshot[1] = 63;

注意我的意图是如何将许多 Datasnapshots 与 DateTime 引用相关联,并使用数据的偏移量来引用其含义。这被确定为在后端存储数据的最有效方式,现在已将其自身反映到以下结构中:

  public class myDataObject { 
    [DataMember]
    public SortedDictionary<DateTime, float[]> Pages { get; set; }

    /// <summary>
    /// An array that identifies what each position in the array is supposed to be
    /// </summary>
    [DataMember]
    public CounterDescription[] Counters { get; set; }
   }

myDataObject 将如何使用?

我会经常按字符串名称搜索计数器,并使用它的位置来确定将保存特定值的偏移量。我可以使用自己开发的扩展方法来枚举对象,或者在保证顺序的情况下利用框架。

此外,随着新传感器的添加,我将需要扩展这些阵列中的每一个:(float[]CounterDescription[]),但是任何已经存在的数据都必须保持在该相对偏移量中。我不希望此对象的序列化版本将 Temp(偏移量 1)与 Humidity(偏移量 0)混淆

哪些 .NET 对象支持这种固定的排序、扩展和枚举(以及可选的按字符串搜索)?我的猜测是使用这些对象之一......

Array[] , LinkedList<t>, and List<t>

【问题讨论】:

  • 视情况而定。你将如何使用它?
  • 这是我在 WCF 中使用的共享类型。在双方(服务器和客户端)上,我将通过字符串名称查找给定计数器的“计数器位置”。我将使用这个基于零的偏移量将数据放入正确的 DataSnapshot 偏移量中。如果添加了新的计数器/数据对,我还需要能够扩展每个数组。
  • 由于会有很多DataSnapshots,我想将CounterDescription 与数据分开。这就是为什么我不使用 Dictionary
  • 您能否澄清一下不使用字典如何将 CounterDescription 与数据分开?
  • 我将在一个实例中上传许多数据快照。换句话说,我有一个带有 CounterDescription[] 的“uploadObject”,并且还有 SortedDictionary DataSnapshot { get;放; }

标签: c# .net arrays memory-management linked-list


【解决方案1】:

使用 Dictionary&lt;string, double&gt; 以便每个名称 (string) 映射到一个值 (double):

var counters = new Dictionary<string, double>();

counters["Humidity"] = 0.9;
counters["Temp"] = 63;

并使用获取和设置计数器值的服务:

[OperationContract]
public double GetCounter(string name)
{
     return Counters[name];
}

[OperationContract]
public void SetCounter(string name, double value)
{
     Counters[name] = value;
}

您可以以相同的方式使用CounterDescription 和/或DataSnapshot 类,但请确保您用作键的类(可能是CounterDescription)覆盖Object.Equals()Object.GetHashCode()实施。

【讨论】:

  • 由于您可能没有看到我的更新,我会按照您的建议做一些类似的事情,并做一个公共 Dictionary 计数器,并实现您提到的覆盖。
【解决方案2】:

如果CounterDescription 是字符串或enum,那么Dictionary 似乎很合适:

Dictionary<string, double> Counters = new Dictionary<string, double>();
// Then initialize it ...
Counters.Add("Humidity", 0);
Counters.Add("Temp", 0);
// To update:
Counters["Humidity"] = 0.9;
// To query
double humidity = Counters["Humidity"];

您可以使用 enum 作为键而不是字符串来做同样的事情。

如果您的CounterDescription 类型是复杂对象,您仍然可以将其用作键,但您需要实现IComparable 或提供比较函数。

【讨论】:

    【解决方案3】:

    任何列表 (IList) 都有有序值。我总是假设单纯的 IEnumerables 在下面没有严格的顺序;尽管他们通常会这样做,但您不能保证。我同意其他人的观点,即字典(或其他一些 IDictionary)非常适合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-23
      • 2015-10-18
      相关资源
      最近更新 更多