1

私はC#にかなり慣れておらず、静的クラス/メソッドを扱うのは非常に初めてです。以前はスタンドアロンでしたが、現在はプラグイン アプリケーションに変換されているアプリケーションに取り組んでいます。グローバル データシートである 1 つのプラグインと、グローバル データシートのコピーを使用するが、モデルを実行する前にそれをさらに操作できるモデルである別のプラグインがあります。そこで、DatasheetControl というカスタム コントロールを作成しました。グローバル データシート プラグインとモデリング プラグインは、コントロールのインスタンスを使用します。スタンドアロン データシートから 2 つの異なるプラグインでこのコントロールにアクセスすることに関連するバグを修正しています。コントロールが列情報の取得と設定に使用するクラスがあります。

public class dtColumnInformation
{
    //table to operate with
    private DataTable _dt = null;
    //dictionary to hold column info
    private Dictionary<string, bool> dictColstatus = null;
    //class variable
    private static dtColumnInformation dtCI = null;

    // method initializes a datatable cols information structure to all enabled
    public dtColumnInformation(DataTable dt)
    {
        if (dt != null)
        {
            _dt = dt.Copy();
            dictColstatus = new Dictionary<string, bool>();

            for (int c = 0; c < _dt.Columns.Count; c++)
            {
                dictColstatus.Add(_dt.Columns[c].ColumnName.ToString(), true);
            }
        }
    }

    // constructor optionally calls method to init the column information structure
    // and return the itself - singleton
    public static dtColumnInformation getdtCI(DataTable dt, bool init)
    {
        //pass null after initialization to access the DTcolInfo property
        //or pass init=true (after import) to initialize
        if (dtCI == null || init) dtCI = new dtColumnInformation(dt);
        return dtCI;
    }

    // method returns the enable/disable status of the column name (key)
    public bool getColStatus(string key)
    {
        //returns the status of a row
        bool boolStatus;
        dictColstatus.TryGetValue(key, out boolStatus);
        return boolStatus;
    }

    // method to set a table column to enable/disable
    public void setColStatus(string key, bool val)
    {
        //sets the status of a column
        dictColstatus[key] = val;
    }

    // property - structure to return column status of all columns in table...
    public Dictionary<string, bool> DTColInfo
    {
        //returns a col-status dictionary for all cols in the datatable
        set { dictColstatus = value; }
        get { return dictColstatus; }
    }

これは、次のような呼び出しでいくつかの場所 (グローバル データシート プラグインを含む) で使用されています。

//(builds dictionary of keys, <string>datetime and values <bool>enabled/disabled col)
dsControl1.DTCI = VBCommon.Metadata.dtColumnInformation.getdtCI(dsControl1.DT, true);

だから、なぜこれがうまくいかないのか理解し始めています。グローバル データシートとモデルの間を行ったり来たりすると、dictColStatus はそれぞれの個別の状態を維持していません。これは、列の見出しを右クリックして、無効な列を有効にするか無効にするかを選択したいときに機能します。この関数のメソッドは、右クリック メニューに入力するオプションを決定するために、dictColStatus の内容を確認します。

コントロールの各インスタンスが維持されるように、この dtColumnInformation クラスの静的なものを静的にならないように変更する必要があります。dtColumnInformation クラスのインスタンスをインスタンス化する必要があることはわかっていますが、

private static dtColumnInformation dtCI = null;

public static dtColumnInformation getdtCI(DataTable dt, bool init)

私を捨てています。彼らが何をしているのか、静的なものを使用しないようにクラス全体で変更を加える方法が正確にはわかりません。ありがとう!

4

1 に答える 1

1

getDtCI()は、単一の値のキャッシュを使用する単なる初期化子です。静的フィールドがまだ初期化されていない場合は、静的フィールドを初期化し、静的フィールドの値を返します。渡されたinitparamがtrueの場合、静的フィールドの新しい値を初期化し、それを返します。静的フィールドの以前の値は破棄されます。init = falseを指定してgetdtCI()を複数回呼び出すと、同じdtColumnInformationインスタンスが返されます。この単一値キャッシュは、大量に要求されたり、構築に費用がかかるもののためにメモリを節約するための努力である可能性があります。

独立したdtColumnInformationオブジェクトを持つ複数のコンテナが必要な場合は、何らかの方法でこれを変更する必要があります。最も簡単なアプローチは、単一アイテムのキャッシュを完全に削除することです。getdtCI()を変更して、常にdtColumnInformationの新しいインスタンスを作成します。getdtCI()への参照を表示して、コードの影響を調査します。dtColumnInformationの構築に膨大な時間やメモリがかからず、コードがgetdtCI()を何百万回も呼び出していない場合は、静的キャッシュを完全に削除して、常にdtColumnInformationの新しいインスタンスを構築できます。

常に新しいdtColumnInformationを作成するのに時間がかかりすぎるか、大量のメモリを消費する場合は、単一アイテムのキャッシュストレージの場所をdtColumnInformationクラスからdtColumnInformationインスタンスを使用するコンテナクラスに移動できます。おそらくそれがDatasheetControlです。これを行う最も直接的な方法は、静的フィールドとgetdtCI()静的メソッドをコンテナークラスに移動することです。

コンテナクラスにアクセスできないgetdtCI()を呼び出すコードに遭遇した場合、この単純なソリューションを使用すると問題が発生します。この点を超えると本当に醜くなります。:P

于 2012-08-30T18:11:14.663 に答える