【问题标题】:return empty List in catch block在 catch 块中返回空列表
【发布时间】:2014-04-11 09:01:57
【问题描述】:

我有一个 c# 函数,它从数据表中读取文件位置,并将包含所有文件 lcoations 的列表返回给调用方法。

Catch 块中,我想返回一个带有 false 的空列表,以便调用方法可以取消它的操作。

但我无法编译我的 return 语句。

传入一个列表作为参考,并让函数返回一个布尔值true/false 会更好吗?

这是我正在尝试的代码:

   public static List<string> getEmailAttachments(string emailID, System.Data.DataTable emails)
    {
        List<string> allAttachments;

        //System.Data.DataTable oTbl = new DataTable();
        try
        {
            System.Diagnostics.Debugger.Break();

            var results = from myRow in emails.AsEnumerable()
                          where myRow.Field<string>("itemID") == emailID
                          select myRow;

            System.Diagnostics.Debug.Print("attachments");
            foreach (DataRow myRow in results)
            {
                System.Diagnostics.Debug.Print(myRow.Field<string>("attachmentsPath"));
                allAttachments.Add(myRow.Field<string>("attachmentsPath"));

                //DataTable dt = (DataTable)myRow["attachmentsPath"];
                //DataTable oTbl = dt.Clone();

                //DataRow[] orderRows = dt.Select("CustomerID = 2");

                //foreach (DataRow dr in orderRows)
                //{
                //    oTbl.ImportRow(dr);
                //}
                // myTable.ImportRow(dr);
                //oTbl.Rows.Add(myRow);
                //oTbl.ImportRow(myRow);
            }

            return allAttachments;
        }
        catch (Exception ex)
        {
            logBuilder("common.getEmailAttachments", "Exception", "", ex.Message, "");

            return new List<string>emptyList(); // cannot compile
        }
    }

【问题讨论】:

  • 附带问题 - 这段代码有哪些类型的异常?也许您可以在不涉及异常的情况下处理这些情况?

标签: c# .net return-value return-type


【解决方案1】:

如果有人还在寻找...

使用IEnumerable&lt;string&gt; 作为返回类型并且:

return Enumerable.Empty<string>();

【讨论】:

  • 被低估的解决方案这个
  • 这其实是抛出空列表的正确解决方案
【解决方案2】:

改变这一行:

return new List<string>emptyList(); // cannot compile

到:

 return new List<string>();

传递一个列表作为引用,并从函数返回一个布尔值,这是一个坏主意。您的方法称为getEmailAttachments,它是加载附件,它应该返回附件。如果你想查看加载附件的结果,我建议你返回null并查看返回值。

【讨论】:

  • 好吧,也许这个名字并不完美,它可以被称为getEmailAttachmentPaths ...你认为我最好传递一个ref字符串数组而不是一个列表吗?
  • No List 没问题,我再次重复在您的情况下传递 ref 参数,这是一个坏主意。
  • 是的,我已将其更改为返回一个列表,并且没有 ref 参数,因为我可以检查返回的列表的大小...(DOH)
  • 也许最好不要抓住......并处理调用者。毕竟这是个例外。
【解决方案3】:

使用

 return new List<string>();

【讨论】:

    【解决方案4】:

    试试这个..

    public static List<string> getEmailAttachments(string emailID, System.Data.DataTable emails)
        {
            List<string> allAttachments;
    
            //System.Data.DataTable oTbl = new DataTable();
            try
            {
                System.Diagnostics.Debugger.Break();
    
                var results = from myRow in emails.AsEnumerable()
                              where myRow.Field<string>("itemID") == emailID
                              select myRow;
    
                System.Diagnostics.Debug.Print("attachments");
                foreach (DataRow myRow in results)
                {
                    System.Diagnostics.Debug.Print(myRow.Field<string>("attachmentsPath"));
                    allAttachments.Add(myRow.Field<string>("attachmentsPath"));
    
                    //DataTable dt = (DataTable)myRow["attachmentsPath"];
                    //DataTable oTbl = dt.Clone();
    
                    //DataRow[] orderRows = dt.Select("CustomerID = 2");
    
                    //foreach (DataRow dr in orderRows)
                    //{
                    //    oTbl.ImportRow(dr);
                    //}
                    // myTable.ImportRow(dr);
                    //oTbl.Rows.Add(myRow);
                    //oTbl.ImportRow(myRow);
                }
    
                //return allAttachments;
            }
            catch (Exception ex)
            {
                logBuilder("common.getEmailAttachments", "Exception", "", ex.Message, "");
    
                allAttachments= new List<string>();
            }
            return allAttachments;
        }
    

    【讨论】:

      【解决方案5】:

      我会采取稍微不同的方法。 我会返回一个空列表,但也将初始容量设置为零!

      像这样:

      return new List<string>(0);//notice the initial capacity to zero.
      

      原因是内存消耗和优化......我知道这是一个微优化,但它不会伤害任何东西。它实际上可能有利于整个应用程序。

      【讨论】:

        【解决方案6】:

        怎么样

        allAttachments.Clear();
        
        return allAttachments;
        

        【讨论】:

        • while (true) { if (!allAttachments.Any()) return allAttachments; allAttachments.RemoveAt(0); }怎么样
        • @Sergey while(true) 是无限循环,是替代答案还是....崩溃算法?
        • 我只是指出没有必要将空列表与try块中填充的列表进行逻辑连接。当我看到这段代码时,我想知道为什么返回 allAttachments 实例很重要——它是通过引用传递的吗?所以,我不会在allAttachments 列表上添加一些错误处理操作,或者如果你想迷惑开发人员,那么循环是一个不错的选择:)
        【解决方案7】:

        自 .Net Framework 4.6 和 Core .Net 版本以来,添加了一种更好的方法,

        return Array.Empty<T>();
        

        这会分配一个数组(它是一个 IList)并将其重用于所有后续对该类型空数组的请求。它又快又干净。

        【讨论】:

          猜你喜欢
          • 2020-12-23
          • 2011-02-11
          • 1970-01-01
          • 1970-01-01
          • 2017-05-15
          • 1970-01-01
          • 2012-05-18
          • 2016-05-06
          • 1970-01-01
          相关资源
          最近更新 更多