我正在开发需要访问元素周期表的科学软件。元素由一组具有一些只读属性(例如质量、丰度、原子序数等)的同位素组成。有 100 多种元素,如果算上同位素,则有超过 1000 种同位素。为了在运行时填充所有这些对象,我当前有一个 XML 文件(构建操作:内容)*,其中包含我在 Element
类的静态构造函数期间解析的所有元素数据:
public class Element {
private static readonly Dictionary<string, Element> _elements;
static Element()
{
_elements = new Dictionary<string, Element>();
LoadElements("Resources/Elements.xml"); // 461 KB file
}
static LoadElements(string resource) {
// code for construction of elements objects and population of the
// _elements dictionary.
}
private Element(blah) { \\ instance constructor }
}
这可行,但是解析文件会产生开销,并且我在设计 Element
类时失去了一些灵活性。另一种方法是将每个同位素和元素硬编码到静态构造函数中。后者的优点是我可以为每个 Element
添加静态只读属性(一个有用的功能):
public class Element {
private static readonly Dictionary<string, Element> _elements;
public static readonly Element Carbon = {get; private set;}
public static readonly Element Hydrogen = {get; private set;}
static Element()
{
_elements = new Dictionary<string, Element>();
Carbon = AddElement("Carbon", 6);
Carbon.AddIsotope(12, 12.0000000, 0.9893);
Carbon.AddIsotope(13, 13.0033548378, 0.0107);
Hydrogen = AddElement("Hydrogen", 1);
//Repeat this pattern for all the elements...
}
static Element AddElement(string name, double atomicNumber)
{
Element element = new Element(name, atomicNumber);
_elements.Add(name, element);
return element;
}
private Element(string name, double atomicNumber) {
// Not Important, just setting readonly properties
}
private void AddIsotope(int massNumber, double mass, double abundance) {
// Not Important;
}
}
但是,这似乎需要包含在 class.cs 文件中的大量硬编码数据。所以我很困惑,一方面,在数据管理级别上,将基本数据存储在读入的外部文件中是有意义的。但另一方面,因为所有数据实际上都是一堆常量/静态只读对象,这种额外的解析工作似乎很及时,但没有成果,并且限制了 API 设计。创建所有这些对象的正确方法是什么?
*注意:如果客户端出于某种原因想要修改元素的值,则将“构建操作”设置为“内容”。这不是必需的,可以更改为嵌入式资源。
最佳答案
我会考虑将值放入嵌入式文件中,但可能具有元素的枚举。 (可能不是同位素,但提供了一种从元素中指定同位素的简单方法。)
这样:
- 您仍然可以拥有强类型 API,而不依赖于用户代码中的魔术字符串等
- 如果您确实愿意,以后仍然可以轻松更改数据(并且可能提供一种从外部源读取数据的方法)
- 您可能会更轻松地使用数据本身(作为 XML 文件而不是 C# 文件)
不用担心解析工作 - 鉴于您只需要执行一次,我发现很难相信它在性能方面会具有重要意义。
关于c# - 在编译代码或外部文件中嵌入大量常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14693865/