首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中,我应该使用枚举、静态类、字典还是结构来表示这些“带标签的浮点数”?

在C#中,我应该使用枚举、静态类、字典还是结构来表示这些“带标签的浮点数”?
EN

Stack Overflow用户
提问于 2013-04-04 21:26:51
回答 7查看 14.9K关注 0票数 14

我有一个恒定的数据结构,它表示每个人类脊椎的相对高度,相对于脊柱总高度进行归一化。这是从人体测量学等研究中得出的。

我在Python中将其实现为元组的元组,每个元组包含一个(字符串)名称和(双精度)值,如下所示:

代码语言:javascript
复制
vertebral_heights = (
("C7",  0.0000000),
("T1",  0.0391914),
("T2",  0.0785479),
("T3",  0.1183993),
("T4",  0.1590759),
("T5",  0.2009076),
("T6",  0.2442244),
("T7",  0.2893564),
("T8",  0.3366337),
("T9",  0.3863861),
("T10", 0.4389439),
("T11", 0.4946370),
("T12", 0.5537954),
("L1",  0.6167492),
("L2",  0.6838284),
("L3",  0.7553630),
("L4",  0.8316832),
("L5",  0.9131188),
("S1",  1.0000000))

我的第一个想法是创建一个Dictionary,但这需要一个类来用作容器。然后我想到了枚举的想法,但我读过“枚举是用来整型的”,我有两个枚举。然后是类和结构,但在这一点上我完全迷惑了,我相信我目前对在C#中做这件事的最佳实践的理解还不够。

我的目标用途是在应用程序模型(元素的数值部分)和用户模型(命名的、与域相关的元素部分)之间建立一个“映射”。

有什么建议吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-04-04 21:37:10

这真的取决于您想要如何访问这些值。

常量

如果您将始终使用变量名,例如:

代码语言:javascript
复制
double x = C7;

然后你可以使用一个充满常量的类,如下所示:

代码语言:javascript
复制
public class VertebralHeights
{
    public const double C7 = 0.0000000d;
}

字典

但是,如果您想要动态访问它们,例如:

代码语言:javascript
复制
string id = "C7";
double x = VertebralHeights[id];

然后,使用Dictionary会更好,您可以这样定义它:

代码语言:javascript
复制
Dictionary<string, double> VertebralHeights = new Dictionary<string, double>()
{
    { "C7", 0.0000000d },
    { "T1", 0.0391914d}
}

有两种方式在一起的。

如果您希望同时使用强类型和动态访问值,则可以扩展上述方法中的任何一种...

对于常量(方法1),添加一个接受字符串的函数:

代码语言:javascript
复制
public double GetValue(string s)
{
    switch(s)
    {
        case "C7": return C7;
        case "T7": return T7;
        //...and so on...
        default: return 0;//or an alternate default
    }
}

(注意:您可以使用反射来实现这一点,使用大量列表会更容易,但在这里不值得额外的性能损失)

对于字典方法(方法2),您可以添加一个getter集合:

代码语言:javascript
复制
public double C7 { get { return VertebralHeights["C7"]; } }
票数 11
EN

Stack Overflow用户

发布于 2013-04-04 21:52:35

这是我对此的看法-使用一个单例类,这是一个字典:

代码语言:javascript
复制
public class Vertebrae : Dictionary<string, double>
{
    private Vertebrae() : base() { }


    private static Vertebrae _heights = new Vertebrae() {
        { "C7", 0.0 },
        { "T1", 0.0391914 },
        { "T2", 0.0785479 },
    };

    public static Vertebrae Heights { get { return _heights; } }

    public static double C7 { get { return Heights["C7"]; } }
    public static double T1 { get { return Heights["T1"]; } }
    public static double T2 { get { return Heights["T2"]; } }

    public static IEnumerable<double> All
    {
        get
        {
            return new List<double>() { C7, T1, T2 };
        }
    }
}

要通过字符串名称访问椎骨,请执行以下操作:

代码语言:javascript
复制
double c7 = Vertebrae.Heights["C7"];

要通过符号名称访问椎骨,请执行以下操作:

代码语言:javascript
复制
double c7 = Vertebrae.C7;

要枚举您的椎骨,请执行以下操作:

代码语言:javascript
复制
foreach (double v in Vertebrae.All) { /* ... */ }

对于枚举器,您可以像在枚举器中一样初始化单个静态列表,但我不确定首先初始化的是静态列表还是静态字典...

票数 7
EN

Stack Overflow用户

发布于 2013-04-04 22:37:36

将其作为枚举,并在前面编写黑盒管道代码。你不会后悔的!这就是我要做的:

编写一个自定义属性,以便可以将双精度值关联到每个枚举:

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
internal sealed class VertebralHeightAsDoubleAttribute : Attribute
{
  public double HeightValue { get; private set; }

  public VertebralHeightAsDoubleAttribute(double heightValue_)
  {
    HeightValue = heightValue_;
  }
}   

一些让生活变得更简单的扩展方法:

代码语言:javascript
复制
public static class VHAttribExtensions
{
  public static string ToNameString(this VertebralHeight target)
  {
    return Enum.GetName(typeof(VertebralHeight), target);
  }

  public static double ToHeightValue(this VertebralHeight target)
  {
    var fi = target.GetType().GetField(target.ToString());
    var attributes = (VertebralHeightAsDoubleAttribute[])fi.GetCustomAttributes(
      typeof(VertebralHeightAsDoubleAttribute), false);
    return attributes.Length > 0 ? attributes[0].HeightValue : double.NaN;
  }
}

使用自定义属性定义枚举:

代码语言:javascript
复制
public enum VertebralHeight
{
  [VertebralHeightAsDouble(0.0000000)]
  C7,
  [VertebralHeightAsDouble(0.0391914)]
  T1,
  [VertebralHeightAsDouble(0.0785479)]
  T2,
  [VertebralHeightAsDouble(0.1183993)]
  T3,
  [VertebralHeightAsDouble(0.1590759)]
  T4,
  [VertebralHeightAsDouble(0.2009076)]
  T5,
  [VertebralHeightAsDouble(0.2442244)]
  T6,
  [VertebralHeightAsDouble(0.2893564)]
  T7,
  [VertebralHeightAsDouble(0.3366337)]
  T8,
  [VertebralHeightAsDouble(0.3863861)]
  T9,
  [VertebralHeightAsDouble(0.4389439)]
  T10,
  [VertebralHeightAsDouble(0.4946370)]
  T11,
  [VertebralHeightAsDouble(0.5537954)]
  T12,
  [VertebralHeightAsDouble(0.6167492)]
  L1,
  [VertebralHeightAsDouble(0.6838284)]
  L2,
  [VertebralHeightAsDouble(0.7553630)]
  L3,
  [VertebralHeightAsDouble(0.8316832)]
  L4,
  [VertebralHeightAsDouble(0.9131188)]
  L5,
  [VertebralHeightAsDouble(1.0000000)]
  S1
}

测试它:

代码语言:javascript
复制
static void Main(string[] args)
{
  var list = Enum.GetValues(typeof(VertebralHeight)).OfType<VertebralHeight>();
  foreach (var vh in list)
  {
    Console.WriteLine("{0} : {1}", vh.ToNameString(), vh.ToHeightValue());
  }
  Console.ReadLine();
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15812640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档