如何在程序启动时初始化一个类?

时间:2010-10-12 15:29:49

标签: c# .net

 class Statistics
{
    Dictionary<decimal, Statistic> BabyDataStandardAgeHeadCircumference;
    Dictionary<decimal, Statistic> BabyDataStandardAgeLength;
    Dictionary<decimal, Statistic> BabyDataStandardAgeWeight;
    Dictionary<decimal, Statistic> BabyDataStandardWeightForLength;


}

这些数据是固定的 - 只读,我想从数据库加载它们。 问题是

  1. 如何让它们只读?(我知道 通过财产)
  2. 如何在程序启动时用数据填充它们?
  3. 从启动事件中调用像Statistics.load()这样的方法对我来说似乎很不好..

6 个答案:

答案 0 :(得分:4)

如果你只使用使用属性,那么词典本身仍然可以修改。一种选择是将它们设为私有,并提供GetXXX方法来检索值。

class Statistics
{
    private static Dictionary<decimal, Statistic> babyDataStandardAgeHeadCircumference;
    private static Dictionary<decimal, Statistic> babyDataStandardAgeLength;
    private static Dictionary<decimal, Statistic> babyDataStandardAgeWeight;
    private static Dictionary<decimal, Statistic> babyDataStandardWeightForLength;

    static Statistics() 
    {
        // Put code to load from database here.  Will get called *once* when 
        // the *class* is first initialized.
    }

    public Statistic GetBabyDataStandardAgeHeadCircumfrence(decimal val) 
    {
        return babyDataStandardAgeHeadCircumfrence[val];
    }

    ...
}

答案 1 :(得分:1)

使其成为只读:使自己成为以只读方式实现IDictionary的包装类。

在应用程序启动时初始化:

  • 如果确实需要精确的初始化操作顺序,Statistics.Load()方法并不奇怪。此外,在数据库连接失败的情况下,这为您提供了合理的错误处理空间。
  • 如果您不必关心初始化顺序,请使用静态构造函数。通过遵循这种方法,您必须确保数据库是可访问的(换句话说,不会有任何合法的错误情况)并且第一次使用该类(实际上触发静态构造函数)不是“太快了“。

答案 2 :(得分:1)

<强>问题:

  

如何让他们只读?(我知道   通过属性)

答案:不要使用Dictionary<decimal, Statistics>,而是考虑为字典使用不可变包装器。

在此处实现不可变Dictionary类的SO链接:

Does C# have a way of giving me an immutable Dictionary?

<强>问题:

  

如何在程序中填充数据   启动?

答案:而不是在程序启动时用数据填充它们,如何在第一次访问类(静态或实例化)时填充它们?这意味着在静态构造函数中填充这些字典(自然地,字典也必须是静态成员)。

public class Statistics
{
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeHeadCircumference;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeLength;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeWeight;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardWeightForLength;

    static Statistics()
    {
        // populate the dictionaries here...
    }
}

答案 3 :(得分:0)

创建一个可以创建,加载和返回Statistics类的类,我将通过接口公开这样做的方法:

public interface IStatisticsRepository {
    Statistics GetStatistics();
}

public class StatisticsRepository : IStatisticsRepository {

    private Statistics _statistics = null;

    private void LoadStatistics() {
         _statistics = GetFromDBHere();
    }

    public Statistics GetStatistics() {
        if (_statistics == null) {
            LoadStatistics();
        }

        return _statistics;

}

然后,您对该接口的实现是一种可以在任何地方使用的服务。我会将它注入您需要的任何地方以获取统计数据。

答案 4 :(得分:0)

实际上,您列出的属性是基于 Dictionary 类的集合。任何可以看到BabyData ...对象的实例都可以访问 Dictionary 中对象的管理( Add(),Remove(),[] indexer )。换句话说,您不能将它们设置为只读,因为Dictionary类不支持通过属性 的操作模式。您必须将 Dictionary 声明为 private ,然后通过方法连接每个 Dictionary 。这是“肮脏”的方法。

或者,您可以基于 Dictionary 类创建一个类,该类通过重载控制对象的添加。这更复杂,但更符合您的需求(从我能理解的内容)。

至于从数据库加载,你需要告诉我们你如何从数据库中获取数据(通过Sql,Linq到Sql,DataSet表适配器等)来确定什么是最好的方法用于将数据提取到 Dictionary 集合中。

答案 5 :(得分:0)

您可以让Statistics类跟随Singleton Pattern;并且在Instance属性中,如果尚未创建实例,则创建一个实例:

class Statistics
{
    private static Statistics sInstance;
    private static Object sInstanceLock = new Object();
    private Statistics() {
        // Load data from database here...
    }
    public static Statistics Instance {
        get {
            lock(sInstanceLock) {
                if(sInstance == null) {
                    sInstance = new Statistics();
                }
                return sInstance;
            }
        }
    }
}

这意味着初始化不一定必须在启动时进行,尽管您可以在启动时调用Instance属性。

至于只读方面,我不确定您的要求是什么。如果你的意思是没有人能够更改字典(添加元素,删除元素),你可以在这里查看问题的答案:Immutable Dictionary。如果你的意思是没有人可以改变存储为字典中特定条目的值的对象,那么你必须使存储在那里的类或值类型不可变,.Net中的String类就是一个例子这个。