7

変換を実行してその結果をプロパティに割り当てる式ツリーを生成するEffortライブラリのコードブロックにエラー処理を追加しようとしています。

既存のコードの問題は、値型のプロパティにnullを割り当てようとしたときに、実行時にこの式が呼び出されたときにNullReferenceExceptionがスローされることです。この場合、割り当てようとしたプロパティに関する情報がないため、より具体的な例外をスローしたいと思います。

以下は、このロジックをtry / catchブロックにカプセル化し、変換が失敗した場合に例外をスローする最初の試みです。最終的には、InvalidOperationExceptionにさらに情報を追加します。

blockElements.Add(
    Expression.TryCatch(
        Expression.Assign(
            Expression.Property(result, this.Properties[i]),
            Expression.Convert(
                Expression.ArrayIndex(parameter, Expression.Constant(i)),
                this.Properties[i].PropertyType)),
        Expression.Catch(typeof(NullReferenceException),
            Expression.Throw(Expression.Constant(
            new InvalidOperationException("Unhandled exception"))))));

私の心の中でこれは私がやろうとしていることです:

try
{
    Property = (int)value;
}
catch (NullReferenceException)
{
    throw new InvalidOperationException("Unhandled exception");
}

ただし、実行時に、その式は「catchの本体はtryの本体と同じタイプである必要があります」というメッセージとともにArgumentExceptionをスローするようになりました。私はここで何が間違っているのですか?スローが原因でヒットすることはありませんが、ダミー値を「返す」ために、Catch式にブロックを作成する必要がありますか?

それとも私はこれに完全に間違った方法でアプローチしていますか?

4

1 に答える 1

10

通常の C# コードでは、メソッド全体が値を返すか、例外をスローする必要があります。

s の場合、Expression動作が少し異なります。各式には戻り値の型があり、 の場合TryCatch、 の戻り値の型はいずれかのs のtry Expression戻り値の型と同じでなければなりません。catch Expression

あなたの場合、の型はtryis ですintが、の型はcatchisvoidであるため、一緒に使用することはできません。これを修正するには、 to のタイプを変更するか、 to のタイプを変更する必要がありtryます。voidcatchint

trytoの型を変更するには、ブロックの型を指定voidできるのオーバーロードをExpression.Block()使用できます (通常、ブロック内の最後の式の型と同じです)。

Expression.TryCatch(
    Expression.Block(
        typeof(void),
        Expression.Assign(…)),
    Expression.Catch(
        typeof(NullReferenceException),
        Expression.Throw(
            Expression.Constant(
                new InvalidOperationException("Unhandled exception")))))

catchtoの型を変更するには、intどうにかして式の型を変更する必要がありますThrow。また、Throw式の場合、任意の戻り値の型が有効になる可能性があるため (実際には返されないため)、戻り値の型を指定できるオーバーロードがあります

Expression.TryCatch(
    Expression.Assign(…),
    Expression.Catch(
        typeof(NullReferenceException),
        Expression.Throw(
            Expression.Constant(
                new InvalidOperationException("Unhandled exception")),
            typeof(int))))

try式全体から実際には何も返したくないので、の型を変更する方が概念的に明確だと思います。

于 2013-01-16T19:45:41.963 に答える