是否可以重写此C#方法重复(Lambdas?Delegates?)?

时间:2015-11-19 20:00:57

标签: c# lambda refactoring

忍受我的lambdas等世界让我的头受伤。我甚至不确定以下代码示例是否有人会使用lambda。

public static void AddDownloadMimeTypesToWebApps()
{
    var webApps = from svc in SPFarm.Local.Services.OfType<SPWebService>()
                  from SPWebApplication webApp in svc.WebApplications
                  where webApp.IsAdministrationWebApplication == false
                  select webApp;
    foreach (SPWebApplication webApp in webApps)
    {
        foreach (FileExtensionData fed in MimeTypes)
        {
            webApp.AllowedInlineDownloadedMimeTypes.Add(fed.MimeType);
        }
        webApp.Update();
    }
}

public static void DeleteDownloadMimeTypesFromWebApps()
{
    var webApps = from svc in SPFarm.Local.Services.OfType<SPWebService>()
                  from SPWebApplication webApp in svc.WebApplications
                  where webApp.IsAdministrationWebApplication == false
                  select webApp;
    foreach (SPWebApplication webApp in webApps)
    {
        foreach (FileExtensionData fed in MimeTypes)
        {
            webApp.AllowedInlineDownloadedMimeTypes.Remove(fed.MimeType);
        }
        webApp.Update();
    }
}

除Add()或Remove()调用外,两种方法都相同。

有没有办法重构这些不涉及一些奇怪的反射调用并将方法名称作为字符串等传递?

干杯!

3 个答案:

答案 0 :(得分:3)

最初,我建议你编写一个获取webApps的方法:

public static IEnumerable<SPWebApplication> GetWebApps()
{
    var webApps = from svc in SPFarm.Local.Services.OfType<SPWebService>()
                  from SPWebApplication webApp in svc.WebApplications
                  where webApp.IsAdministrationWebApplication == false
                  select webApp;
    return webApps;   
}

然后,尽管其余代码非常相似,但由于它们做了不同的事情,我不会将它们加入到一个方法中。

public static void AddDownloadMimeTypesToWebApps(IEnumerable<SPWebApplication> webApps)
{
    foreach (var webApp in webApps)
    {
        foreach (var fed in MimeTypes)
        {
            webApp.AllowedInlineDownloadedMimeTypes.Add(fed.MimeType);
        }
        webApp.Update();
    }
}

public static void DeleteDownloadMimeTypesFromWebApps(IEnumerable<SPWebApplication> webApps)
{
    foreach (var webApp in webApps)
    {
        foreach (var fed in MimeTypes)
        {
            webApp.AllowedInlineDownloadedMimeTypes.Remove(fed.MimeType);
        }
        webApp.Update();
    }
}

现在你有三种不同的方法,有三种不同的职责。第一个GetWebApps返回WebApps的序列。第二个将下载mime类型添加到您作为参数传递的Web应用AddDownloadMimeTypesToWebApps,最后一个DeleteDownloadMimeTypesFromWebApps删除它们。

这样很容易记住每种方法究竟是什么。他们的目的非常明确。此外,您不会向方法的消费者隐藏所需的输入。例如,有人读取第二种方法的名称。第一个问题是哪些网络应用程序?在原始代码中,我们没有将Web应用程序作为参数传递,我们在mehtod的主体内部获取它们。这没有意义,因为根据方法的名称,我们只想将下载mime类型添加到某些Web应用程序而不是获取它们然后添加donwload mime类型。

最后但并非最不重要的是,因为对于添加和删除的情况,Web应用程序的检索都是相同的,我们必须将其分离为一种可以完全满足此要求的方法。最后一个动作不仅增强了上面提到的内容,而且它也是DRY原则的明确设备,不重复自己,这有助于我们编写更易于维护的代码。现在,如果将来任何时候你必须在检索网络应用程序时做一些改变,你将只有一个地方,你必须看,而不是两个或更多的地方。

答案 1 :(得分:2)

我们可以将这个独特的代码变成lambda:

private static void DownloadMimeTypesToWebApps(Action<SPWebApplication,FileExtensionData> action)
{
    var webApps = from svc in SPFarm.Local.Services.OfType<SPWebService>()
              from SPWebApplication webApp in svc.WebApplications
              where webApp.IsAdministrationWebApplication == false
              select webApp;
    foreach (SPWebApplication webApp in webApps)
    {
       foreach (FileExtensionData fed in MimeTypes)
       {
           action.Invoke(webApp,fed);
       }

       webApp.Update();
    }   

}

public static void AddDownloadMimeTypesToWebApps()
{
    DownloadMimeTypesToWebApps((webApp,fed) => webApp.AllowedInlineDownloadedMimeTypes.Add(fed.MimeType));
}

public static void DeleteDownloadMimeTypesToWebApps()
{
    DownloadMimeTypesToWebApps((webApp,fed) => webApp.AllowedInlineDownloadedMimeTypes.Remove(fed.MimeType));        
}

答案 2 :(得分:-1)

如果只是一个普通的旧参数,还有其他?:

///sequelize.d.ts
findAll( options? : FindOptions ) : Promise<Array<TInstance>>;
///bluebird.d.ts
declare class Promise<R> implements Promise.Thenable<R>, Promise.Inspection<R> {
    constructor(callback: (resolve: (thenableOrResult: R | Promise.Thenable<R>) => void, reject: (error: any) => void) => void);
}

易于阅读。很容易维持任何级别。