为什么不调用我的静态构造函数 [英] Why isn't my static constructor being called

查看:51
本文介绍了为什么不调用我的静态构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用两个类来实现字符串枚举模式.问题是在调用父类的运算符时未调用子类的静态构造函数.有没有一种方法可以解决此问题,而无需在代码中添加hack来初始化静态成员?

I have two classes that I'm trying to use to implement a string enumeration pattern. The problem is the static constructor for the child class isn't being called when an operator of the parent class is called. Is there a way I can fix that without adding a hack to the code to initialize the static members?

public abstract class BaseStringEnum<T> where T : BaseStringEnum<T>
{
    public string Value { get; private set; }

    private static List<T> _values = null;
    protected static List<T> Values 
    {
        get
        {
            if (_values == null)
            {
                _values = new List<T>();
            }

            return _values;
        }
    }

    protected BaseStringEnum(string value, string resId)
    {
        Value = value;
        ResourceId = resId;

        Values.Add((T)this);
    }

    public static implicit operator string(BaseStringEnum<T> value)
    {
        return value.Value;
    }

    public static implicit operator BaseStringEnum<T>(string value)
    {
        return Values.Where(v => v.Value.Trim() == value.Trim()).First();
    }
}


public sealed class UseTimeStringEnum : BaseStringEnum<UseTimeStringEnum>
{
    private UseTimeStringEnum(string value, string resourceId) : base(value, resourceId) { }

    public static readonly UseTimeStringEnum None;// = new UseTimeStringEnum("N", "None");
    public static readonly UseTimeStringEnum Required;// = new UseTimeStringEnum("R", "Required");
    public static readonly UseTimeStringEnum Optional;// = new UseTimeStringEnum("O", "Optional");

    static UseTimeStringEnum()
    {
        None = new UseTimeStringEnum("N", "None");
        Required = new UseTimeStringEnum("R", "Required");
        Optional = new UseTimeStringEnum("O", "Optional");
    }
}

问题是,当代码尝试执行(UseTimeStringEnum)"R" 之类的操作时,它失败了,因为静态构造函数尚未触发.我觉得应该触发,因为我使用的是静态运算符.

The problem is when the code tries to do something like (UseTimeStringEnum)"R" it fails because the static constructor hasn't fired yet. I feel like it should fire because I'm using a static operator.

推荐答案

一旦满足以下条件之一,便会调用某个类的静态构造函数:

Static constructor of some class is called once one of the following conditions is met:

  1. 该类的实例已创建;
  2. 访问该类的任何静态字段.

由于您既没有创建UseTimeStringEnum的实例,也没有创建代码中的静态字段,因此不会调用静态构造函数.

Since you do not create instances of UseTimeStringEnum neither acess it's static fields within your code, the static constructor is not called.

因此,重点是:编译时BaseStringEnum不知道UseTimeStringEnum.

So the point is: BaseStringEnum does not know of UseTimeStringEnum at the compile time.

我看到了唯一合适的解决方案-我们可以在运行时引用UseTimeStringEnum.

I see the only proper solution - we can refer UseTimeStringEnum at the runtime.

我将静态构造函数添加到BaseStringEnum类中,该类将加载并观察带有反射的所有可用子类.

I added static constructor to the BaseStringEnum class wich loads and observes all available subclasses with Reflection.

现在调用了静态构造函数.

now the static constructor is called.

Mykroft指出,有一种方法可以直接调用静态构造函数,而不是通过反射引用静态字段.所以我相信最终的代码段应该是

Mykroft pointed there is the way to call a static constructor directly instead of referencing static fields with reflection. So i believe the final code snippet should be

static BaseStringEnum()
{
    var StringEnumTypes = AppDomain.CurrentDomain.GetAssemblies()
          .SelectMany(a => a.GetTypes())
          .Where(type => type.IsSubclassOf(typeof(BaseStringEnum<T>)));

    foreach (var type in StringEnumTypes) type.TypeInitializer.Invoke(null, null);
}

这篇关于为什么不调用我的静态构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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