在编译代码或外部文件中嵌入大量常量

时间:2013-02-04 19:16:36

标签: c# .net constants chemistry

我正在开发需要访问元素周期表的科学软件。 Element包含一组Isotopes,其具有一些只读属性(例如质量,丰度,原子序数等)。有超过100种元素,当考虑其同位素时,有超过1000种同位素。要在运行时填充所有这些对象,我目前有一个XML文件(Build Action:Content)*,其中包含我在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类时会失去一些灵活性。另一种方法是将每个IsotopeElement硬编码到静态构造函数中。后者的优点是我可以为每个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设计。创建所有这些对象的正确方法是什么?

*注意:如果客户端出于某种原因想要修改元素的值,则将Build Action设置为Content。这不是必需的,可以更改为嵌入式资源。

2 个答案:

答案 0 :(得分:3)

我会考虑将值放在嵌入式文件中,但可能具有元素的枚举。 (可能不是同位素,但提供了一种从元素中指定同位素的简便方法。)

那样:

  • 您仍然可以使用强类型API,而不是依赖于用户代码中的魔术字符串等
  • 如果您真的希望(以及可能提供从外部源读取数据的方式),您仍然可以轻松地更改数据。
  • 您可能更容易使用数据本身,作为XML文件而不是C#

不要担心解析工作 - 假设您只需要一次,我发现很难相信它在性能方面会很重要。

答案 1 :(得分:0)

查看sourceforge上托管的蓝色方尖碑项目 - 我想你会在那里找到一些有用的东西,甚至可能正是你正在寻找的东西。