0

フィルタリング/検索の方法がありますが、これWindows Formは検索を提供するすべてのものに対して作成されています。この大量の繰り返しコードを回避できるように、基本クラスでジェネリックメソッドを作成しようとしています。

これが私が修正したい元のコードです:

private void LoadData()
{
    GridFilter filter = new GridFilter();
    filter.AddRule(dgvColDescription.DataPropertyName, txtDescription.Text);

    if (cboColor.SelectedIndex != -1)
    {
        filter.AddRule(dgvColMaterialColorId.DataPropertyName, cboColor.SelectedValue.ToString());
    }
    ...
    //a lot more of this filter.AddRule stuff 
    ...
 }

ここには2つのことがあると思います。インスタンスの必要性GridFilterと、使用する必要のある2種類のコントロールです。

これが一般的な方法の私の試みであると言った:

protected virtual void AddFilterRules<T>(Control ctrl, String str) where T : GridFilter
{
    T filter;
    if (ctrl is ComboBox)
    {
        if ((ctrl as ComboBox).SelectedIndex != -1)
        {
            filter.AddRule(/*dgvColMaterialColorId.DataPropertyName*/ str, (ctrl as ComboBox).SelectedValue.ToString());
        }
    }

    if (ctrl is TextBox)
    {
        filter.AddRule(/*dgvColCode.DataPropertyName*/str, ctrl.Text);
    }
}

コメントされた部分を文字列として渡すことができるかどうかまだわからないため、いくつかのコメントがありますが、私にとってより大きな問題はIDEfilter変数についてから得られるエラーです。

割り当てられていないローカル変数「フィルター」の使用

結局、それからジェネリックメソッドを作ることは可能ですか?どうすればそれを行うことができますか?

4

4 に答える 4

2

new()メソッドに制約を追加します。

protected virtual void AddFilterRules<T>(Control ctrl, String str) where T : GridFilter, new()

その後

T filter = new T();

それか、パラメータとしてTを渡します。

protected virtual void AddFilterRules<T>(T filter, Control ctrl, String str) where T : GridFilter
于 2013-03-01T14:47:38.563 に答える
1

構文は正しいですが、他に2つの問題があります。

  1. あなたはT何にも初期化していない。それはnullあなたがそれを使おうとしている時点での参照です。渡すつもりでしたTか?

  2. で何もしていませんT返品する必要がありますTか?または、それを他のオブジェクトのプロパティに割り当てますか?

への参照を渡しT、メソッド内でそれを変更すると、両方の問題が解決されます。

protected virtual void AddFilterRules<T>(T filter, Control ctrl, String str)
     where T : GridFilter
{
    ...
}

ただし、その場合、メソッドは一般的である必要はまったくありません。

protected virtual void AddFilterRules(GridFilter filter, Control ctrl, String str)
{
    ...
}
于 2013-03-01T14:47:45.353 に答える
1

なぜジェネリックメソッドを使用したいのですか?

フィルターが常に a のGridFilter場合、メソッドでそのタイプを使用できます。このような派生クラスを使用してSpecialGridFilterも機能します。GridFilter元のメソッドで毎回新しいメソッドを作成するという事実は、新しいメソッドでそれを行うことができることを意味します。したがって、いくつかの値を渡すという事実にもかかわらず、新しいメソッドは必要ありません。

型パラメーターと通常のパラメーターを混同しているようです。型パラメーターを持つことは、その型のインスタンスを取得することを意味しません。これは、タイプごとに明示的にコーディングしなくても、同じアルゴリズムを異なるタイプに使用できることを意味します。

ジェネリック実装が本当に必要な場合は、ジェネリック パラメータで型制約を使用できますwhere T : GridFilter, new()new T()これにより、ジェネリック メソッドでを作成できます。

新しい方法はどこに実装されますか?

GridFilter現在どのように実装されているかはわかりませんが、AddRule変更されているようです。その場合、すべての変更が失われるため、毎回新しいインスタンスを作成しないでください。AddFilterRulesしたがって、 もGridFilterクラスのメンバーである必要があり、各フォームには のインスタンスが必要GridFilterです。

の実装を変更できない場合GridFilterでも、拡張メソッドを使用できます。GridFilter毎回新しいものを作成するのが正しい場合は、Form型に拡張メソッドを含めることができます。これは、どのように機能するかによって異なりGridFilterます。

于 2013-03-01T15:24:43.450 に答える
0

Tのインスタンスを作成する必要があります。

T filter = new GridFilter();

Tが常にである場合はGridFilter、TをGridFilterに置き換えることもできます。

protected virtual void AddFilterRules<GridFilter>(Control ctrl, String str)
{
    GridFilter filter = new GridFilter();
    ...
}

ただし、一般的な方法を使用するべきではないと思います。GridFilterを返すメソッドを作成する必要があります。

protected virtual GridFilter AddFilterRules(Control ctrl, String str)
{
    GridFilter filter = new GridFilter();
    ...

    return filter;
}
于 2013-03-01T14:48:18.077 に答える