2

私は次のクラスを持っています:

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

私が抱えている問題は、静的クラスが最初に使用されるときに、が作成されていないことです。これは、基本クラスのメソッドを介したChangeoverものWithdrawalです。つまり、電話をかけると、空になります。InstallationResolveResolveCache

ただし、のようなことを行うとDocketType foo = DocketType.Changeover;Application_Startすべての静的フィールドが作成され、Cache3つの値すべてが含まれます。

このシナリオが機能するようにこれらの静的フィールドを作成する正しい方法は何ですか?

4

2 に答える 2

7

アクセスしているのが。だけの場合、のフィールドを初期化するDocketType 必要はないと思いますEnumeration<>DocketTypeを呼び出すときに、タイプをまったく参照していませんEnumeration<>.Resolve()。静的メソッドまたは静的フィールドにアクセスするたびに、CLRは本当にすべてのサブクラスを初期化する必要がありますか?それはあなたのコードを遅くし、そしてほとんどの場合不必要にそうします。

C#でできるように書いてみることができDocket.Resolve()ますが、これが以前とは異なるものにコンパイルされるかどうかはわかりません。コンパイラがそれを変換するだけでEnumeration<DocketType, int, string>.Resolve()、sqaureに戻る可能性があります。

正直なところ、私はあなたのコード構造に欠陥があることを示唆する傾向があります、そしてあなたが遭遇している問題はその症状です。Cache何かを含むことに依存する必要はありません。そのタイプを使用していないときに発生した静的タイプの初期化に依存する必要はありません。

したがって、オプションは次のとおりです。

  • DocketTypeメソッドのどこかに無意味な参照を入れてMain()、初期化が確実に行われるようにし、コード構造に欠陥がある可能性があるという考えを持ってください。
  • 静的フィールドを別のタイプ、おそらくEnumeration<>それ自体に移動します。これにより、欠陥は軽減されますが、完全には解決されません。
  • コードの基本的な構造を考えて再設計し、キャッシュがいっぱいになることに依存する必要がないようにします。
于 2010-08-10T13:35:56.123 に答える
2

編集:あなたがベースタイプだけを参照していることに気づいていませんでした。それには間違いなく問題があります-DocketTypeその場合、型初期化子を実行することは保証されていません。DocketTypeキャッシュを使用するメソッドを呼び出していると思いました。

この場合、以前は機能していなかったでしょう。ジェネリック型の引数として型を使用しても、私が知る限り、型の初期化は強制されません。それがあなたが求めていることです。

これを機能させるのは難しいと思います。基本的に、型の初期化を引き起こしたいのですが、それを行う良い方法がわかりません。リフレクションを使用して型初期化子を呼び出すことができますが、それを1回だけ行うように非常に注意する必要があります。

私はTimwiに同意します。あなたの最善の解決策は、これを必要としないように設計を再構築することだと思います。

于 2010-08-10T13:24:00.673 に答える