8

私には次の2つの関数がありますが、これらはほぼ同じですが、唯一の違いは、一方がを使用しfunc、もう一方がを使用することactionです。そして、可能であれば、それらを1つの機能にまとめたいと思います。

    private static void TryCatch(Action action)
    {
        try
        {
            action();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }

    private static TResult TryCatch<TResult>(Func<TResult> func)
    {
        try
        {
            return func();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }
4

3 に答える 3

4

これら2つをC#で1つの関数に結合することは、実際には不可能です。C#およびCLRのvoidinは単純に型ではないため、非void関数とは異なる戻りセマンティクスを持ちます。このようなパターンを適切に実装する唯一の方法は、voidおよび非voidデリゲートにオーバーロードを提供することです。

CLRの制限は、すべてのCLR言語で実行することが不可能であることを意味するわけではありません。void値を返さない関数を表すために使用する言語では、それは不可能です。このパターンは、値を返さないメソッドUnitの代わりにを使用するため、F#で非常に実行可能です。void

于 2012-06-04T16:24:40.453 に答える
4

2番目のFunc<T>バージョンを使用してAction、アクションをラムダでラップするだけでメソッドを実装できます。これにより、重複したコードの一部が排除されます。

private static void TryCatch(Action action)
{
    Func<object> fun => 
       {
           action();
           return null;
       };
    TryCatch(fun);
}

そうは言っても、これを行うには余分なオーバーヘッドが伴うので、個人的には、おそらく現在の実装のままにしておきます(特に、この場合、元のバージョンがどれほど短くて単純であるかを考えると)。

于 2012-06-04T16:25:08.360 に答える
1

@ReedCopseyが示唆するように私はこれを行います。

これは私が見つけた最も単純な構文です:

private static void TryCatch( Action action )
{
    TryCatch( () => { action(); return 0; } );
}
于 2012-06-04T16:32:42.773 に答える