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

Can this C# method duplication be rewritten (Lambdas? Delegates?)?

忍受 lambda 等世界让我头疼。我什至不确定下面的代码示例是否有人会使用 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() 调用外,这两种方法完全相同。

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

干杯!

如果只是一个普通的旧参数又如何呢?:

public static void EditMimeTypesToWebApps(int editType) // maybe you can make it an enum
{
    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)
        {   
            if(editType == 0)
            {
                webApp.AllowedInlineDownloadedMimeTypes.Remove(fed.MimeType);
            }
            else
            {
                webApp.AllowedInlineDownloadedMimeTypes.Add(fed.MimeType);
            }
        }
        webApp.Update();
    }
}

足够容易阅读。任何级别都可以轻松维护。

最初,我建议您编写一个获取 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,returns一个序列的WebApps。第二个将下载 mime 类型添加到您作为参数传递的 Web 应用程序,AddDownloadMimeTypesToWebApps,最后一个 DeleteDownloadMimeTypesFromWebApps 删除它们。

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

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

像这样我们可以将唯一代码设为 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));        
}