0

汎用デリゲートをパラメーターとして受け取り、それをリストに挿入するメソッドがあります。

public void AddFilterMember<T>(Func<T, bool> filterMember)
{
    filter.Add(filterMember);
}

その後、タイプTのインスタンスに対してすべてのデリゲートが呼び出され、このインスタンスがフィルターを通過するかどうか、つまり、呼び出されたすべてのfilterMemberに対してtrueが返されるかどうかが確認されます。

次のような無効なラムダ式を渡すことができることに気付きました。

string str = null;
AddFilterMember(x => str.Contains((string)x));

str文字列がnullであるため、呼び出されると明らかに例外がスローされます。したがって、ラムダ式が定義された時点で、null 参照 (パラメーター以外) に対してラムダ式を検証する最良の方法を知りたいですか?

T の既定のインスタンスを使用して呼び出すことも 1 つのオプションだと思いますが、T には既定のパラメーターなしのコンストラクターがない可能性があるため、これが実行できない場合があります。

前もって感謝します!

4

3 に答える 3

1

私は通常このようにします:

AddFilterMember(
     x => {
           if(str == null) 
             throw new ArgumentNullException("str cannot be null");                     
           str.Contains((string)x)
          });
于 2012-06-17T14:04:57.010 に答える
1

考えられる解決策は次のとおりです。

public bool AddFilterMember<T>(Func<T, bool> filterMember, T checkValue = default(T))
{
    try
    {
        filterMember(checkValue);
    }
    catch
    {
        return false;
    }
    filter.Add(filterMember);
    return true;
}

呼び出し元がそれが機能しdefault(T)ないことを知っていても、実際に使用されるすべての値が機能することを期待しcheckValueている場合、例として を指定できます。そこから、デリゲートを実行して、機能するかどうかを確認するだけです。Aboolが返され、呼び出し元に呼び出しが成功したかどうかが通知されます。

デリゲートを呼び出すと、副作用が発生する可能性があることに注意してください。発信者が驚かないように、この動作は文書化する必要があります。

于 2012-06-17T14:10:57.683 に答える
0

関連する質問と考えられる答え:

リフレクション-ラムダ式内のメソッド呼び出しのリストを取得します

しかし、実際の実行の周りにtry..catchがなければ、ラムダ式が後でスローされるかどうかを決定することはNP完全問題です。

特に、例のように、ラムダが、式が実行されるたびにnullになる場合とnullにならない場合がある変数を参照している場合。ラムダがチェックしない場合、それはスローする可能性があります。

re:一部のTにはデフォルト値がありません。

おそらくキャスト:ラムダ(T)nullのテスト用です。try..catch具体的にはについて質問していたからですNullReferenceException

-ジェシー

于 2012-06-17T14:19:15.817 に答える