代码之家  ›  专栏  ›  技术社区  ›  djdd87

当对静态类的第一次访问是基类上的静态方法时,为什么我的静态对象没有被实例化?

  •  2
  • djdd87  · 技术社区  · 15 年前

    public class DocketType : Enumeration<DocketType, int, string>
    {
        public static DocketType ChangeOver = new DocketType(1, "Changeover");
        public static DocketType Withdrawal = new DocketType(2, "Withdrawal");
        public static DocketType Installation = new DocketType(3, "Installation");
    
        private DocketType(int docketTypeId, string description) 
            : base(docketTypeId, description)
        {
        }
    }
    

    具有以下基类:

    public abstract class Enumeration<TEnum, X, Y> : IComparable 
        where TEnum : Enumeration<TEnum, X, Y> 
        where X : IComparable 
        where Y : IComparable
    {        
        protected Enumeration(X value, Y displayName)
        {
            AddToStaticCache(this);
        }
        public static TEnum Resolve(X value)
        {
            return Cache[value] as TEnum;
        }
    }
    

    我的问题是 Changeover Withdrawal Installation 当第一次使用静态类是通过 Resolve 基类中的方法。如果我打电话 ,那么 Cache

    但是,如果我做了 DocketType foo = DocketType.Changeover; 在里面 Application_Start ,然后创建所有静态字段,然后 具有所有三个值。

    创建这些静态字段的正确方法是什么?

    2 回复  |  直到 15 年前
        1
  •  7
  •   Timwi    15 年前

    DocketType 应该 Enumeration<> . 您没有引用 案卷类型 当你打电话的时候,请随时打字 Enumeration<>.Resolve() . CLR真的应该初始化所有 子类 每次访问静态方法或静态字段时?它会减慢代码的速度,而且在大多数情况下是不必要的。

    你可以试着写 Docket.Resolve() ,C#允许您这样做,但我不知道这是否会编译成与以前不同的东西;编译器可能会把它变成 Enumeration<DocketType, int, string>.Resolve() 你又回到了斯考尔一号。

    Cache

    因此,您的选择是:

    • 在你生命中的某个地方 Main() 方法来确保初始化的发生,并接受代码结构可能有缺陷的想法。
    • 也许可以将静态字段移到另一种类型 它本身减轻了缺陷,但并不能完全解决它。
    • 考虑一下你的代码的基本结构,重新设计它,这样你就不必依赖于缓存被填满了。
        2
  •  2
  •   Jon Skeet    15 年前

    只有 指的是基本类型。这肯定有问题-没有什么可以保证运行的类型初始化 DocketType 案卷类型 然后使用了缓存。

    我想你很难让这件事成功。基本上你想激发类型初始化,我不知道一个好的方法。您可以使用反射调用类型初始值设定项,但必须非常小心,不要只调用一次。

    我同意蒂姆维的观点:我认为你最好的解决方案是重新设计你的设计,这样你就不需要这个了。