web-dev-qa-db-ja.com

非パラメーター関数を返す関数

私はc#でこのような関数を見つけました:

  private Dictionary<string, Func<string>> ObtenerExtraCfgCampo(MsgDefCamp camp)
    {
        var extra = new Dictionary<string, Func<string>>();
        extra.Add("Oddity", () => camp.Order % 2 == 0 ? "Even" : "Odd");
        extra.Add("Odd", () => camp.Order % 2 == 0 ? "Odd" : string.Empty);
        extra.Add("Even", () => camp.Order % 2 != 0 ? "Even" : string.Empty);
        extra.Add("MsgPath", () => campo.MsgPath);
        return extra;

    }

これにユーティリティはありますか?このようにした方がいいでしょう

private Dictionary<string, string> ObtenerExtraCfgCampo(MsgDefCamp camp)
{
    var extra = new Dictionary<string, string>();
    extra.Add("Oddity",  camp.Order % 2 == 0 ? "Even" : "Odd");
    extra.Add("Odd",  camp.Order % 2 == 0 ? "Odd" : string.Empty);
    extra.Add("Even",  camp.Order % 2 != 0 ? "Even" : string.Empty);
    extra.Add("MsgPath",  campo.MsgPath);
    return extra;

}

キャンプを変えると、機能の振る舞いも変わると思います。しかし、それはあまりにもリスクが高く、推論するのが難しいのではないですか?この点が足りないのかな

4
Adrian Godoy

タイプのわずかな違いを無視して、最初の結果を操作すると、campcurrent状態が表示されますが、2番目はsome previousの状態が表示されますcamp(つまり、ObtenerExtraCfgCampoが呼び出されたとき、おそらく数十億ナノ秒前).

それらは異なることをするので、互換性はありません。変更可能な状態への他の参照よりも危険ではありません。

私はほとんどのアプリでDictionary<Whatever, string>sからDictionary<Whatever, Func<string>>s実行時に言語を変更できるようにする

6
Caleth

そのポイントが何であるかを確認するには、データを変更してメソッドの2つのバージョンを実行してみてください たとえば、何が起こるかの例については、ここを参照してください

Funcを使用する最初のバージョンでは、MsgDefCampインスタンスのクロージャーが必要です。つまり、ディクショナリに問い合わせると現在の値が取得されるため、この例では、メソッドが呼び出されたときに値がオフだったとしても、「Even」と報告されます。

2番目のバージョンは、メソッドが呼び出されたときにMsgDefCampインスタンスの内容を評価し、それらの結果を辞書に格納します。したがって、Orderが変更されても、ディクショナリの値は変更されず、「奇数」が報告されます。

このようなコードに慣れていない場合を推論するのは難しい場合があります。それは信じられないほど便利な言語機能ですが、慣れるに値します。

3
David Arno