当首次访问静态类是基类上的静态方法时,为什么不能实例化我的静态对象? [英] Why are my static objects not being instantiated when first access to the static class is a static method on the base class?

查看:140
本文介绍了当首次访问静态类是基类上的静态方法时,为什么不能实例化我的静态对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

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

我遇到的问题是,当第一次使用静态类是通过基类中的Resolve方法时,没有创建ChangeoverWithdrawalInstallation. IE.如果我呼叫Resolve,则Cache将为空.

The problem I have is that Changeover, Withdrawal and Installation are not being created when the first time that the static class is used is via the Resolve method in the base class. I.e. if I call Resolve, then Cache will be empty.

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

However, if I do something like DocketType foo = DocketType.Changeover; in Application_Start, then all of the static fields get created and then Cache has all three values.

创建这些静态字段的正确方法是什么,以使这种情况起作用?

What's the correct way to create these static fields so this scenario works?

推荐答案

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

I don’t think the fields in DocketType should be initialised when all you’re accessing is Enumeration<>. You are not referencing the DocketType type at all when you call Enumeration<>.Resolve(). Should the CLR really initialise all subclasses every time you access a static method or static field? It would slow down your code, and in most cases unnecessarily so.

您可以尝试编写Docket.Resolve(),C#允许您这样做,但是我不知道它是否可以编译成与以前不同的格式;编译器可能只是将其转换为Enumeration<DocketType, int, string>.Resolve(),您又回到了原来的状态.

You could try writing Docket.Resolve(), which C# allows you to do, but I don’t know whether this will compile into something different than before; the compiler might just turn it into Enumeration<DocketType, int, string>.Resolve() and you’re back to sqaure one.

说实话,我倾向于建议您的代码结构有缺陷,而您遇到的问题就是这种现象的征兆.您不必依赖Cache包含某些内容.当您不使用静态类型初始化时,您不必依赖它.

To be honest, I am inclined to suggest that your code structure is flawed, and the problem you’re running into is a symptom of that. You shouldn’t have to rely on Cache containing something. You shouldn’t have to rely on some static type initialisation to have occurred when you’re not using that type.

因此,您的选择是:

  • 在您的Main()方法中的某处放置对DocketType的无意义引用,以确保初始化发生,并接受代码结构可能存在缺陷的想法.
  • 将静态字段移动到另一种类型,也许是Enumeration<>本身,这可以减轻缺陷但不能完全解决问题.
  • 考虑一下代码的基本结构,然后重新设计它,以使您不必依赖于已填充的缓存.
  • Put a pointless reference to DocketType somewhere in your Main() method to ensure the initialisation happens, and live with the idea that your code structure may be flawed.
  • Move the static fields to another type, perhaps Enumeration<> itself, which alleviates the flaw but doesn’t completely solve it.
  • Think about the fundamental structure of your code and redesign it so that you don’t have to rely on the cache being filled.

这篇关于当首次访问静态类是基类上的静态方法时,为什么不能实例化我的静态对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆