为什么不调用我的静态构造函数 [英] Why isn't my static constructor being called
问题描述
我尝试使用两个类来实现字符串枚举模式.问题是在调用父类的运算符时未调用子类的静态构造函数.有没有一种方法可以解决此问题,而无需在代码中添加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:
- 该类的实例已创建;
- 访问该类的任何静态字段.
由于您既没有创建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屋!