Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何才能清理这个丑陋的if语句?_C#_.net - Fatal编程技术网

C# 我如何才能清理这个丑陋的if语句?

C# 我如何才能清理这个丑陋的if语句?,c#,.net,C#,.net,我有以下丑陋的if语句,它是从IOC容器中提取的类的一部分: protected virtual void ExecuteSourceControlGet(IBuildMetaData buildMetaData, IPackageTree componentTree) { if ((buildMetaData.RepositoryElementList != null) && (buildMetaData.RepositoryElementList.Count >

我有以下丑陋的if语句,它是从IOC容器中提取的类的一部分:

protected virtual void ExecuteSourceControlGet(IBuildMetaData buildMetaData, IPackageTree componentTree)
{
    if ((buildMetaData.RepositoryElementList != null) && (buildMetaData.RepositoryElementList.Count > 0))
    {
        componentTree.DeleteWorkingDirectory();

        foreach (var repositoryElement in buildMetaData.RepositoryElementList)
        {
            repositoryElement.PrepareRepository(componentTree, get).Export();
        }

    }

    if((buildMetaData.ExportList != null) && (buildMetaData.ExportList.Count > 0))
    {
        var initialise = true;

        foreach (var sourceControl in buildMetaData.ExportList)
        {
            log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), sourceControl.Url);

            get.From(sourceControl).ExportTo(componentTree, sourceControl.ExportPath, initialise);

            initialise = false;
        }

    }

    log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), buildMetaData.SourceControl.Url);

    get.From(buildMetaData.SourceControl).ExportTo(componentTree);
}
我通常消除if语句的方法是为每个条件创建一个子类

此示例的不同之处在于:

  • 具有此方法的类将从IOC容器中提取
  • 我可能希望运行或根本不运行两个if语句之间的逻辑

  • 非常欢迎任何建议。

    我不太清楚为什么要删除if语句,而使用继承似乎有些过头了。您可能希望为重复的集合代码创建扩展方法:

    public static bool HasElements<T>(this ICollection<T> collection)
    {
        return collection != null && collection.Count != 0;
    }
    

    在我看来,这稍微简单一点。如果有更多的逻辑,你可能还想把这两个块分成不同的方法。除此之外,我不会担心

    哦,还有另一种扩展方法,如果您需要关心是否有元素,它不会有帮助,但是如果您只想执行空安全的foreach,它会有帮助:

    public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
    {
        return source ?? Enumerable.Empty<T>();
    }
    
    公共静态IEnumerable EmptyIfNull(此IEnumerable源代码)
    {
    返回源??可枚举的.Empty();
    }
    
    (无可否认,使用空合并操作符内联使用会节省很多时间…

    受保护的虚拟void ExecuteSourceControl集
    (IBuildMetaData元数据,IPackageTree树)
    {
    if(metaData.RepositoryElementList.HasElements())
    {
    DeleteWorkingDirectory();
    foreach(metaData.RepositoryElementList中的var元素)
    元素.PrepareRepository(树,get.Export();
    }
    if(metaData.ExportList.HasElements())
    {
    var init=true;
    foreach(metaData.ExportList中的var sourceControl)
    {
    log.InfoFormat
    (“\nHorn正在获取{0}。\n\n”.ToUpper(),sourceControl.Url);
    get.From(源控件)
    .ExportTo(树,sourceControl.ExportPath,init);
    init=false;
    }
    }
    log.InfoFormat
    (“\n horn正在获取{0}。\n\n”.ToUpper(),
    metaData.SourceControl.Url);
    get.From(metaData.SourceControl)
    .出口到(树);
    }
    //荣誉归于乔恩·斯基特。。。
    公共静态类集合扩展
    {
    公共静态布尔元素(此ICollection集合)
    {
    返回集合!=null&&collection.Count!=0;
    }
    }
    
    使用两种提取方法,并反转要保护的if如何:

    protected virtual void ExecuteSourceControlGet(IBuildMetaData buildMetaData, IPackageTree componentTree)
    {
       ExecuteRepositoryElementList(buildMetaData.RepositoryElementList, componentTree);
    
       ExecuteExportList(buildMetaData.ExportList, componentTree);
    
       log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), buildMetaData.SourceControl.Url);
    
       get.From(buildMetaData.SourceControl).ExportTo(componentTree);
    }
    
    private void ExecuteRepositoryElementList(RepositoryElementList repositoryElements, IPackageTree componentTree)
    {
       // Guard: No elements
       if (repositoryElements == null || repositoryElements.Count == 0) return;
    
       componentTree.DeleteWorkingDirectory();
    
       foreach (var repositoryElement in repositoryElements)
       {
          repositoryElement.PrepareRepository(componentTree, get).Export();
       }
    }
    
    private void ExecuteExportList(ExportList exportList, IPackageTree componentTree)
    {
       // Guard: No elements
       if(exportList == null || exportList.Count == 0) return;
    
       var initialise = true;
    
       foreach (var sourceControl in exportList)
       {
          log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), sourceControl.Url);
    
          get.From(sourceControl).ExportTo(componentTree, sourceControl.ExportPath, initialise);
    
          initialise = false;
       }
    }
    

    顺便说一句:这两个方法必须使用正确类型的IBILDMetadata.RepositoryElementListIBILDMetadata.ExportList来固定。我要么按照John的建议创建一个扩展方法,要么(如果这在您的其他类的上下文中有意义的话)重构它,使buildMetaData成为类的成员,并具有两个带有get的私有bool属性,该get使用更可读的内容屏蔽dual子句if语句


    任何一种方法都可以达到同样的效果,使其更具可读性。

    你到底为什么要删除任何东西?添加子类只是为了去掉“if”?我可以很容易地理解您的代码,因此它具有很高的可读性。没有理由改变,我也是这么想的。看不出那些if语句有什么真正的错误
    public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
    {
        return source ?? Enumerable.Empty<T>();
    }
    
    protected virtual void ExecuteSourceControlGet
        (IBuildMetaData metaData, IPackageTree tree)
    {
        if (metaData.RepositoryElementList.HasElements())
        {
            tree.DeleteWorkingDirectory();
    
            foreach (var element in metaData.RepositoryElementList)
                 element.PrepareRepository(tree, get).Export();    
        }
    
        if(metaData.ExportList.HasElements())
        {
            var init = true;
    
            foreach (var sourceControl in metaData.ExportList)
            {
                log.InfoFormat
                  ("\nHorn is fetching {0}.\n\n".ToUpper(), sourceControl.Url);
    
                get.From(sourceControl)
                  .ExportTo(tree, sourceControl.ExportPath, init);
    
                init = false;
            }
    
        }
    
        log.InfoFormat
           ("\nHorn is fetching {0}.\n\n".ToUpper(), 
               metaData.SourceControl.Url);
    
        get.From(metaData.SourceControl)
           .ExportTo(tree);
    }
    
    //Credits goes to Jon Skeet...
    public static class CollectionExtensions
    {
        public static bool HasElements<T>(this ICollection<T> collection)
        {
            return collection != null && collection.Count != 0;
        }
    }
    
    protected virtual void ExecuteSourceControlGet(IBuildMetaData buildMetaData, IPackageTree componentTree)
    {
       ExecuteRepositoryElementList(buildMetaData.RepositoryElementList, componentTree);
    
       ExecuteExportList(buildMetaData.ExportList, componentTree);
    
       log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), buildMetaData.SourceControl.Url);
    
       get.From(buildMetaData.SourceControl).ExportTo(componentTree);
    }
    
    private void ExecuteRepositoryElementList(RepositoryElementList repositoryElements, IPackageTree componentTree)
    {
       // Guard: No elements
       if (repositoryElements == null || repositoryElements.Count == 0) return;
    
       componentTree.DeleteWorkingDirectory();
    
       foreach (var repositoryElement in repositoryElements)
       {
          repositoryElement.PrepareRepository(componentTree, get).Export();
       }
    }
    
    private void ExecuteExportList(ExportList exportList, IPackageTree componentTree)
    {
       // Guard: No elements
       if(exportList == null || exportList.Count == 0) return;
    
       var initialise = true;
    
       foreach (var sourceControl in exportList)
       {
          log.InfoFormat("\nHorn is fetching {0}.\n\n".ToUpper(), sourceControl.Url);
    
          get.From(sourceControl).ExportTo(componentTree, sourceControl.ExportPath, initialise);
    
          initialise = false;
       }
    }