6

メソッドチェーンを使用して、かなりきれいに記述できるメソッドがあります。

return viewer.ServerReport.GetParameters()
    .Single(p => p.Name == Convention.Ssrs.RegionParamName)
    .ValidValues
    .Select(v => v.Value);

ただし、連鎖メソッドのいずれかが予期しない結果を返した場合に役立つ診断情報を提供したいので、各ポイントでいくつかのチェックを実行できるようにしたいと思います。

ifこれを実現するには、すべてのチェーンを分割し、各呼び出しをブロックで追跡する必要があります。コードが読みにくくなります。

理想的には、チェーンされたメソッド呼び出しを織り込んで、各ポイントで予期しない結果を処理できるようにしたいと思います(たとえばnew ConventionException("The report contains no parameter")、最初のメソッドが空のコレクションを返す場合など、意味のある例外をスローします)。誰かがそのようなことを達成するための簡単な方法を提案できますか?

編集:

これは、@JeffreyZhaoの回答を使用した結果です。

return viewer.ServerReport.GetParameters()
    .Assert(result => result.Any(), "The report contains no parameter")
    .SingleOrDefault(p => p.Name == Convention.Ssrs.RegionParamName)
    .Assert(result => result != null, "The report does not contain a region parameter")
    .ValidValues
    .Select(v => v.Value)
    .Assert(result => result.Any(), "The region parameter in the report does not contain any valid value");
4

3 に答える 3

7

多分あなたはこのアプローチを使うことができます。

static T Check<T>(this T value)
{
    if (...) throw ...;

    return value;
}

それから:

xxx.Single(...).Check().Select(...).Check()...

アップデート:

あなたもできます:

static T Validate<T>(this T value, Func<T, bool> validate, string errorMessage)
{
    if (!validate(value)) 
        throw new ValidationFailedException(errorMessage);

    return value;
}

それから:

xxxx.Single()
    .Validate(v => v > 0, "Must be greater than zero")
    .NextStep()
    .Validate(...);
于 2012-06-07T10:18:38.253 に答える
1

ローカル変数を使用して、プロセスを個別のステップに簡単に分割できます。

var result1 = viewer.ServerReport.GetParameters();
var result2 = result1.Single(p => p.Name == Convention.Ssrs.RegionParamName);
var result3 = result2.ValidValues;
var result4 = result3.Select(v => v.Value);
return result4;

これで、ステップ間で必要なチェックを実行できます。

ただし、一部の結果は実際には機能しないことに注意してください。たとえば、最後のステップでは結果としてリストが生成されず、から読み取る列挙子が生成されるため、ValidValuesこのメソッド内ではなく、結果を使用すると、そのステップでエラーが発生します。.ToList()結果を実現するために、いくつかのステップの最後に追加することをお勧めします。

于 2012-06-07T10:25:15.900 に答える
1

コードコントラクトの使用を検討してください(たとえばServerReport.GetParameters、メソッドが空のコレクションを返さないようにするために事後条件を追加します)。独自のチェックロジックを作成するよりも、よりエレガントな方法で必要なことを実行できます。

class ReportParameter { }
class ServerReport
{
    public ReportParameter[] GetParameters()
    {
        Contract.Ensures(Contract.Result<ReportParameter[]>() != null && Contract.Result<ReportParameter[]>().Length > 0,
            Resource1.Oops);

        // here's some logic to build parameters array...
        return new ReportParameter[0];
    }
}

使用法:

// Oops! I need at least one parameter!
var parameters = new ServerReport().GetParameters();
于 2012-06-07T10:33:26.117 に答える