最后介绍如何用try-catch重构代码

本文关键字:try-catch 重构 代码 何用 最后 | 更新日期: 2023-09-27 18:27:22

我必须创建一堆看起来像这样的方法。更改的内容将是方法名称、返回类型和中间标记的行,其余内容将相同。有没有一种干净的方法来重构它,这样我就不会重复了?

private bool CanPerform(WindowsIdentity identity, string applicationName, int operation)
{
    IAzApplication3 application = null;
    IAzClientContext3 context = null;
    try
    {
        application = this.store.OpenApplication(applicationName, null) as IAzApplication3;
        ulong token = (ulong)identity.Token.ToInt64();
        context = application.InitializeClientContextFromToken(token, null) as IAzClientContext3;
        // lines that change go here
    }
    catch (COMException e)
    {
        throw new SecurityException(string.Format("Unable to check operation '{0}'", operation), e);
    }
    finally
    {
        Marshal.FinalReleaseComObject(context);
        Marshal.FinalReleaseComObject(application);
    }
}

我意识到这可能是最基本的东西,但我一个人工作,所以没有其他人可以问。

最后介绍如何用try-catch重构代码

听起来委托在这里是合适的,用一个通用方法来覆盖返回类型的变化:

private T ExecuteWithIdentity<T>(WindowsIdentity identity,
    string applicationName, int operation,
    Func<IAzApplication3, IAzClientContext3, T> action)
{
    IAzApplication3 application = null;
    IAzClientContext3 context = null;
    try
    {
        application = this.store.OpenApplication(applicationName, null) as IAzApplication3;
        ulong token = (ulong)identity.Token.ToInt64();
        context = application.InitializeClientContextFromToken(token, null) as IAzClientContext3;
        return action(application, context);
    }
    catch (COMException e)
    {
        throw new SecurityException(
            string.Format("Unable to check operation '{0}'", operation), e);
    }
    finally
    {
        Marshal.FinalReleaseComObject(context);
        Marshal.FinalReleaseComObject(application);
    }
}

然后将每个检查的代码放在一个单独的方法中,甚至只使用lambda表达式:

bool check = ExecuteWithIdentity(identity, "Foo", 10,
                         (application, context) => context != null);

string check = ExecuteWithIdentity(identity, "Foo", 10, SomeComplexAction);
...
private static string SomeComplexAction(IAzApplication3 application,
                                        IAzClientContext3 context)
{
    // Do complex checks here, returning whether the user is allowed to
    // perform the operation
}

您可能想要更改课程的委托类型——例如,operation的用途尚不清楚。

我也强烈考虑铸造,而不是使用as。如果应用程序或上下文是作为非null值从OpenApplication/InitializeClientContextFromToken返回的,而这不是正确的类型,您真的想将其处理为返回的null值吗?

您可以在堆栈稍高的位置进行错误处理,因此,与其在方法内部捕获并重新引发异常,不如在调用方法的位置进行处理?

如果您的方法调用都封装在Manager类中,这可能会节省一些时间。如果他们只是在任何地方临时调用,那么自然可能不会:)

我希望这会有所帮助。