我有一个恒定的数据结构,它表示每个人类脊椎的相对高度,相对于脊柱总高度进行归一化。这是从人体测量学等研究中得出的。
我在Python中将其实现为元组的元组,每个元组包含一个(字符串)名称和(双精度)值,如下所示:
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#中做这件事的最佳实践的理解还不够。
我的目标用途是在应用程序模型(元素的数值部分)和用户模型(命名的、与域相关的元素部分)之间建立一个“映射”。
有什么建议吗?
发布于 2013-04-04 21:37:10
这真的取决于您想要如何访问这些值。
常量
如果您将始终使用变量名,例如:
double x = C7;然后你可以使用一个充满常量的类,如下所示:
public class VertebralHeights
{
public const double C7 = 0.0000000d;
}字典
但是,如果您想要动态访问它们,例如:
string id = "C7";
double x = VertebralHeights[id];然后,使用Dictionary会更好,您可以这样定义它:
Dictionary<string, double> VertebralHeights = new Dictionary<string, double>()
{
{ "C7", 0.0000000d },
{ "T1", 0.0391914d}
}有两种方式在一起的。
如果您希望同时使用强类型和动态访问值,则可以扩展上述方法中的任何一种...
对于常量(方法1),添加一个接受字符串的函数:
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集合:
public double C7 { get { return VertebralHeights["C7"]; } }发布于 2013-04-04 21:52:35
这是我对此的看法-使用一个单例类,这是一个字典:
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 };
}
}
}要通过字符串名称访问椎骨,请执行以下操作:
double c7 = Vertebrae.Heights["C7"];要通过符号名称访问椎骨,请执行以下操作:
double c7 = Vertebrae.C7;要枚举您的椎骨,请执行以下操作:
foreach (double v in Vertebrae.All) { /* ... */ }对于枚举器,您可以像在枚举器中一样初始化单个静态列表,但我不确定首先初始化的是静态列表还是静态字典...
发布于 2013-04-04 22:37:36
将其作为枚举,并在前面编写黑盒管道代码。你不会后悔的!这就是我要做的:
编写一个自定义属性,以便可以将双精度值关联到每个枚举:
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
internal sealed class VertebralHeightAsDoubleAttribute : Attribute
{
public double HeightValue { get; private set; }
public VertebralHeightAsDoubleAttribute(double heightValue_)
{
HeightValue = heightValue_;
}
} 一些让生活变得更简单的扩展方法:
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;
}
}使用自定义属性定义枚举:
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
}测试它:
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();
}https://stackoverflow.com/questions/15812640
复制相似问题