8

これらのチェックボックスがあるとしましょう:

  • FooCheckBox
  • バーチェックボックス
  • バズチェックボックス

そしてこれらの方法:

  • フー
  • バー
  • バズ

対応するチェックボックスがチェックされている場合にのみ、各メソッドを呼び出したいです。コードは次のようになります。

void DoWork()
{
    if (FooCheckBox.Checked)
    {
        Foo();
        Console.WriteLine("Foo was called");
    }

    if (BarCheckBox.Checked)
    {
        Bar();
        Console.WriteLine("Bar was called");
    }

    if (BazCheckBox.Checked)
    {
        Baz();
        Console.WriteLine("Baz was called");
    }
}

ここで、3 つのチェックボックスと 3 つのメソッドの代わりに、もっと多くのものがあると考えてください。上記のコードをよりDRYにするためにどのように書き直しますか?

4

5 に答える 5

7

あなたが提示したケースについては、そのままにしておきます。コードベースの保守性が低下する可能性があるため、正当な理由なしに過度に抽象化することは望ましくありません。もちろん、コンテキストは重要ですが、最終的には判断が必要です。

とはいえ、これが私がこれにアプローチする方法です。各項目にコントロールとアクション デリゲートの両方が含まれるコレクションを作成します。次に、ループして各項目に対してロジックを実行します。

var items = new KeyValuePair<CheckBox, Action>[] {
    new KeyValuePair<CheckBox,Action>(FooCheckBox, Foo),
    new KeyValuePair<CheckBox,Action>(BarCheckBox, Bar),
    new KeyValuePair<CheckBox,Action>(BazCheckBox, Baz)
};

foreach (var item in items)
{
    if (item.Key.Checked) 
    {
        item.Value.Invoke();
        Console.WriteLine("Invoked " + item.Value.Method.Name);
    }
}

または(おそらく?)Linqを使用する方が良い:

items.Where(item => item.Key.Checked).ToList().ForEach(item => new {
    item.Value.Invoke();
    Console.WriteLine("Invoked " + item.Value.Method.Name);
});
于 2012-06-23T22:04:21.857 に答える
6

ディクショナリを使用して、どのアクションがどのチェックボックスを参照しているかを把握できます。次に、次のことができます。

foreach(KeyValuePair<CheckBox, Action> kvp in Dict)
{
    if(kvp.Key.Checked)
        kvp.Value.Invoke();
}
于 2012-06-23T22:02:23.273 に答える
4

簡単にするために、私は一緒に行きます

void DoWork()
{
    DoIfChecked(FooCheckBox, Foo, "Foo as Called");
    DoIfChecked(BarCheckBox, Bar, "Bar as Called");
    DoIfChecked(BazCheckBox, Baz, "Baz as Called");
}
void DoIfChecked(CheckBox checkBox, Action action, string message)
{
    if (checkBox.IsChecked)
    {
        action();
        Console.WriteLine(message);
    }
}

しかし、それがそれほど単純な場合は、メッセージ部分で何かを行うことができます。ローカルのコンテキストに応じて、いくつかのエラー チェックをスローする可能性があります。

于 2012-06-23T22:13:01.543 に答える
2

次の方法で実行できます。

void DoWork()
{
    Func<Action, string, Tuple<Action, string>> toT = 
        (a, s) => new Tuple<Action, string>(a, s);

    var map = new Dictionary<CheckBox, Tuple<Action, string>>
    {
        {FooCheckBox, toT(Foo, "Foo")},
        {BarCheckBox, toT(Bar, "Bar")},
        {BazCheckBox, toT(Baz, "Baz")},
    };

    foreach (var x in map.Keys)
        if (x.Checked)
        {
            map[x].Item1();
            Console.WriteLine(map[x].Item2 + " was called");
        }
}

でも、あまりDRYでなくても大丈夫な場合もあると思います。

于 2012-06-23T22:07:07.893 に答える
0

Dictionarywithを作成し、<CheckBox, Func>各値をループします。

Dictionary<CheckBox, Func> checkboxes = new Dictionary<CheckBox, Func>();
void Init()
{
    checkboxes.Add(FooCheckBox, Foo);
    checkboxes.Add(BarCheckBox, Bar);
    checkboxes.Add(BazCheckBox, Baz);
}

void DoWork()
{
    foreach (KeyValuePair<CheckBox, Func> checkbox in checkboxes)
    {
        if (checkbox.Key.Checked)
        {
            checkbox.Value();
            Console.WriteLine("{0} was called", checkbox.Text);
        }
    }
}
于 2012-06-23T22:07:55.773 に答える