静态字段的奇怪行为

时间:2010-12-08 17:20:42

标签: c# .net generics static-constructor

我正在尝试使用自定义枚举类,这使我能够创建具有用户友好标识符和任意关联值的枚举。到目前为止一切顺利:

public class EnumBase<T, E>
    where E : class
{
    private static readonly List<E> list = new List<E>();

    private string text;
    private T value;

    public string Text { get { return text; } }
    public T Value { get { return value; } }

    public EnumBase(string text, T value)
    {
        this.text = text;
        this.value = value;
        list.Add(this as E);
    }

    protected static IEnumerable<E> ItemList
    {
        get { return list; }
    }
}

public class Zahlungsart : EnumBase<int, Zahlungsart>
{
    public static readonly Zahlungsart Erlagsschein = new Zahlungsart("Erlagsschein", 0);
    public static readonly Zahlungsart Lastschrift = new Zahlungsart("Lastschrift", 1);

    private Zahlungsart(string text, int value) : base(text, value) { }
    public static new IEnumerable<Zahlungsart> ItemList { get { return EnumBase<int, Zahlungsart>.ItemList; } }
}

现在我的问题是:

Console.WriteLine(Zahlungsart.ItemList.Count());

以下陈述给出0而不是2.问题是由于beforefieldinit,我认为。我可以通过直接调用特定枚举的某些方法来解决这个问题,这会强制加载静态字段,但我认为这不是最佳解决方案。

提示:请不要在这里提出某种[UserfriendlyName()] - 枚举属性,我已经知道了。

修改 谢谢,汉斯。我的代码中确实有一个拼写错误,调用错误的泛型专业化。

现在我的问题是,我可以摆脱每个子类中ItemList的重新定义,但似乎有必要初始化静态字段。

2 个答案:

答案 0 :(得分:2)

如何使用“静态构造函数”??

public class Zahlungsart : EnumBase<int, Zahlungsart>
{
    public static readonly Zahlungsart Erlagsschein;
    public static readonly Zahlungsart Lastschrift;

    static Zahlungsart()
    {
        Erlagsschein = new Zahlungsart("Erlagsschein", 0);
        Lastschrift = new Zahlungsart("Lastschrift", 1);
    }

    private Zahlungsart(string text, int value) : base(text, value) { }
    public static new IEnumerable<Zahlungsart> ItemList { get { return EnumBase<int, Zahlungsart>.ItemList; } }
}

答案 1 :(得分:1)

您的代码不会重现问题。但如果你改变这样的属性,你会得到一个repro:

    public new static IEnumerable<Zahlungsart> ItemList { 
        get { return EnumBase<uint, Zahlungsart>.ItemList; }   // Note: uint instead of int
    }

请注意,从泛型类型生成的每个具体类都有自己的静态字段,它们共享。