2

我有以下课程:

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;
    }
}

我遇到的问题是,当第一次使用静态类是通过基类中的方法时ChangeoverWithdrawal并没有被创建。即如果我打电话,那么将是空的。InstallationResolveResolveCache

但是,如果我执行类似DocketType foo = DocketType.Changeover;in 的操作Application_Start,则会创建所有静态字段,然后Cache具有所有三个值。

创建这些静态字段的正确方法是什么,以便这种情况有效?

4

2 回答 2

7

我认为当DocketType 访问的只是Enumeration<>. DocketType当您调用时,您根本没有引用类型Enumeration<>.Resolve()。每次访问静态方法或静态字段时,CLR 是否真的应该初始化所有子类?它会减慢你的代码,而且在大多数情况下是不必要的。

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

老实说,我倾向于认为您的代码结构存在缺陷,而您遇到的问题就是其中的一个症状。你不应该依赖于Cache包含某些东西。当您不使用该类型时,您不必依赖某些静态类型初始化。

因此,您的选择是:

  • DocketType在您的方法中对某处进行无意义的引用以Main()确保初始化发生,并接受您的代码结构可能存在缺陷的想法。
  • 将静态字段移动到另一种类型,可能是Enumeration<>它本身,这可以减轻缺陷但并不能完全解决它。
  • 考虑一下代码的基本结构并重新设计它,这样您就不必依赖正在填充的缓存。
于 2010-08-10T13:35:56.123 回答
2

编辑:我没有意识到你只是指基本类型。这肯定有问题——在这种情况下,不能保证运行类型初始化程序DocketType。我以为您正在调用一个方法DocketType,然后在其中使用缓存。

在这种情况下,它以前也不会起作用。据我所知,使用类型作为泛型类型参数不会强制类型初始化,这就是您所追求的。

我认为你很难让它发挥作用。基本上你想激发类型初始化,我不知道这样做的好方法。您可以使用反射调用类型初始化程序,但您必须非常小心,只执行一次。

我同意 Timwi:我认为你最好的解决方案是重组你的设计,这样你就不需要这个了。

于 2010-08-10T13:24:00.673 回答