c# - 如何使用 try-catch-finally 重构代码

标签 c# refactoring

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

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);
    }
}

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

最佳答案

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

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
}

当然,您可能想要更改委托(delegate)类型 - 例如,不清楚 operation 的用途。

我也会强烈考虑转换而不是使用 as。如果应用程序或上下文从 OpenApplication/InitializeClientContextFromToken 返回为非 null 值,这不是正确的类型,您是否真的要处理相同的作为返回的空值?

关于c# - 如何使用 try-catch-finally 重构代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9662549/

相关文章:

c# - telerik radgrid 控制详细信息屏幕在单击主记录时不刷新

java - 如何从方法中提取依赖于类上下文的变量以避免重复代码?

language-agnostic - 如何将静态调用排除在类之外

c# - 依赖注入(inject)——当你有很多依赖时怎么办?

java - 如何用许多 if 结构重构一个大函数?

c# - 为什么我的日期值在 web api 函数中解析不正确?

c# - 用于查找 .NET 中特定程序集使用的所有方法和类的工具?

c# - 读取本地组策略/Active Directory 设置

c# - 在使用 MigraDoc 生成的 PDF 中无法显示圆加号 (⊕)

asp.net-mvc - 重构经典 ASP 的最佳实践?