2010-12-08 2 views
2

사용자 친화적 인 식별자와 임의의 관련 값을 사용하여 열거 형을 만들 수있는 사용자 정의 열거 형 클래스를 가져 오려고합니다. 지금까지 너무 좋은 :정적 필드의 이상한 동작

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()); 

다음 명령문은 나에게 공을 제공, 문제는 beforefieldinit 예정이다 대신 2, 나는 생각한다. 이 문제를 해결하려면 특정 열거 형의 일부 메서드를 직접 호출하여 정적 필드를로드해야하지만이 방법은 최상의 솔루션이 아닙니다.

힌트 : 여기에 enum에 대한 [UserfriendlyName()] 속성을 제안하지 마십시오. 이미 알고 있습니다.

수정 감사합니다. 나는 틀린 일반적인 전문화를 부르는 나의 자신의 부호에있는 참으로 오타가, 있었다.

이제 내 질문에, 각 하위 클래스에서 ItemList 재정의 제거 할 수 있지만 정적 필드를 초기화하는 데 필요한 것으로 보인다.

+0

정확히 동일한 코드를 실행하면 "2"가 출력됩니다. – cdhowie

답변

1

코드는 문제를 재현하지 않습니다. 이 같은 속성을 변경하는 경우 그러나 당신이 생식을 얻을 것이다 :

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

은 제네릭 형식에서 생성 된 모든 구상 클래스가 자신의 정적 필드있을 것이라는 점을주의를, 그들이 공유 하지입니다.

+0

젠장, 당신이 옳다. 나는 실제로 코드가 작동하는 코드를 둘러 보았다. :) – codymanix

+0

각 서브 클래스에서 ItemList를 재정의 할 수 있습니까? 그것이 없으면 정적 ctor가 호출되지 않습니다. 이것은 파생 클래스의 첫 번째 정적 멤버에 액세스 할 때까지 count가 0임을 의미합니다. – codymanix

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

컴파일러는 이미 자동으로 cctor를 생성하여 읽기 전용 멤버를 초기화합니다. 이것은 어떤 변화도 가져올 수 없습니다. –

+0

@ 한스, 가능합니다. 정적 생성자는 "beforefieldinit"플래그를 제거하여 유형이 처음 사용될 때 모든 정적 필드가 실행되도록합니다. 정적 생성자가없는 형식은 "beforefieldinit"로 표시되며 정적 필드는 처음 참조되기 전에 만 초기화되지만 모든 형식이 다른 코드가 실행되기 전에 초기화된다는 보장이 없습니다. http://www.yoda.arachsys.com/csharp/beforefieldinit.html – sisve

+0

왜 잘못된 대답이 그렇게 많은 점수를 얻습니까? – codymanix