【问题标题】:how to use try catch blocks in a value returning method?如何在值返回方法中使用 try catch 块?
【发布时间】:2011-04-27 11:32:18
【问题描述】:

我正在检查注册表中上传的图像,我需要在其中使用 try catch 块。这是我的代码:

public bool CheckFileType(string FileName)
{
        string Ext = Path.GetExtension(FileName);
        switch (Ext.ToLower())
        {
            case ".gif":                   
                return true;
                break;
            case ".JPEG":                    
                return true;
                break;
            case ".jpg":                  
                return true;
                break;
            case ".png":                   
                return true;
                break;
            case ".bmp":                   
                return true;
                break;
            default:                  
                return false;
                break;
        }

}

请在这里建议我如何使用 try catch 块。

提前致谢。

【问题讨论】:

  • 为什么需要“使用 try catch 块”?到目前为止,您尝试过什么?
  • 您认为代码的哪一部分会引发异常?
  • 如果您寻找小写扩展名,为什么要使用 .JPEG?
  • 您应该接受对您问题的回答。
  • 另外你也不必使用 return and break,因为 return 无论如何都充当了一个 break 并结束了方法。

标签: c# asp.net


【解决方案1】:

这样会更好,

 public bool CheckFileType(string FileName)
 {
    bool result = false ;

    try
     {
      string Ext = Path.GetExtension(FileName);
      switch (Ext.ToLower())
      {
        case ".gif":                   
        case ".JPEG":                    
        case ".jpg":                  
        case ".png":                   
        case ".bmp":                   
            result = true;
            break;
       }

      }catch(Exception e)
      {
         // Log exception 
      }
      return result;
     }

【讨论】:

  • @Henk :在你指出之前注意到它,无论如何感谢你的及时友好射击;)
  • 比较 ".JPEG" 和 Ext.ToLower() 不太可能匹配 ;)
  • 这里如何使用try/catch?好的,您只需将它们放入方法的主体中即可。我喜欢这个答案
【解决方案2】:

有很多方法可以在返回值的方法中使用异常:

将 return 语句放在 try-catch 之外 例如:

T returnValue = default(T);
try
{
    // My code
}
catch 
{
    // Exception handling code
}
return returnValue;

在你的 catch 中添加一个 return 语句

try
{
    // My code
}
catch 
{
    // Handle exception
    return default(T);
}

抛出异常

您没有必须返回一个值,该方法只需要结束(例如,到达 return 语句或 throw 语句)。根据异常,返回值并不总是有效。

您应该仔细考虑何时以及如何捕获和处理异常:

  1. 什么可能会失败?
  2. 他们为什么/怎么会失败?
  3. 失败时我该怎么办?

在你的情况下:

  1. 唯一可能失败的语句是string Ext = Path.GetExtension(FileName);,根据documentation,如果FileName 包含,它可能会失败。 (请注意,GetExtension 不返回 null,即使 FileName 为 null)。
  2. 如果用户提供的字符串包含这些无效字符,则可能会发生这种情况。
  3. 如果发生这种情况,我想我们应该返回 false,表示路径无效(但这取决于应用程序)。

所以我可能会像这样处理异常:

public bool CheckFileType(string FileName)
{
    string Ext;
    try
    {
        Ext = Path.GetExtension(FileName);
    }
    catch (ArgumentException ex)
    {
        return false;
    }
    // Switch statement
}

请注意,我们只捕获我们预期的异常 (ArgumentException),并且我们只将 try 语句放在我们希望从其中引发异常的语句周围。

事实上,尽可能避免抛出和捕获异常是个好主意——它们不仅会导致性能损失(如果在循环内调用此方法会导致严重问题),而且您可能会无意中捕获和处理异常您没有预料到的异常,掩盖了更严重的问题。

在这种情况下,我们可以通过检查FileName 是否包含任何无效字符来完全避免抛出异常:

public bool CheckFileType(string FileName)
{
    if (FileName == null)
    {
        return false;
    }
    if (FileName.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
    {
        return false;
    }
    // Your original method goes here
}

【讨论】:

  • 我不喜欢追ArgumentException。我宁愿只用 if 检查文件名中的无效字符。除此之外,很好的答案。 +1。
  • 我认为,在这种特殊情况下,如果发生错误,它应该在堆栈中冒泡,而不是在此方法中被捕获\处理。
  • @Martinho Heh,我只是在您发布的内容中添加 :-)
  • 不幸的是(只是阅读它):“不能保证从此方法返回的数组包含文件和目录名称中无效的完整字符集。” :(
  • @data_smith 这取决于应用程序 - 在这种情况下,我会说检查自己或允许抛出异常都很好,捕获/屏蔽异常不太有利,但是我展示了它无论如何,因为在许多情况下,您无法帮助抛出异常(例如在 IO 中),它演示了如何考虑异常(可能抛出什么?为什么会抛出?我该怎么办?)
【解决方案3】:

由于您实际上并未测试文件类型(仅测试文件名的扩展名),因此我首先要重命名该方法。您可以制作一个扩展方法来处理它:

public static bool HasImageExtension(this string fileName)
{
    try
    {
        if (fileName == null) return false;

        string[] validExtensions = new string[] { ".gif", ".jpg", ".jpeg", ".png", ".bmp" };

        string extension = Path.GetExtension(fileName);
        return validExtensions.Contains(extension);
    }
    // catch the specific exception thrown if there are 
    // invalid characters in the path
    catch (ArgumentException ex) 
    {
        // do whatever you need to do to handle 
        // the fact there are invalid chars
        throw; 
    }
}

然后您可以调用它,如下所示:

string fileName = "testFileName.jpg";
bool hasImageExtension = fileName.HasImageExtension();

【讨论】:

  • 其实Path.GetExtension如果路径包含无效字符也会抛出
  • @Groo:是的,你是对的 - 完全毁了我的答案,是时候更新了;)
【解决方案4】:

这应该可行:

public bool CheckFileType(string FileName)
{
    try
    {
        string Ext = Path.GetExtension(FileName).ToLower();
        string[] okExt = ".gif|.jpg|.jpeg|.png|.bmp".Split('|');

        foreach(var item in okExt)
        {
            if(Ext == item)
                return true;
        }
        return false;
    }
    catch(Exception ex)
    {
        throw;
    }
}

请记住:永远不要捕获您不会处理的异常。(或至少重新抛出它们)

【讨论】:

  • 否则 return false; 是我所缺少的。
  • 修复了上述问题。
  • 或者,您可以使用 LINQ:return ".gif|.jpg|.jpeg|.png|.bmp".Split('|').Any(e => e.Equals(Ext));
  • 我认为这可能更清楚; return new List { ".gif", ".jpeg", ".jpg", ".png", ".bmp" }.Contains(ext);
  • 遗憾的是 LINQ 并不总是可用,在这种情况下,使用 LINQ 并不会获得太多收益。
猜你喜欢
  • 2014-04-30
  • 1970-01-01
  • 2016-08-26
  • 2021-03-29
  • 2020-11-27
  • 1970-01-01
  • 2012-05-18
  • 2018-11-05
  • 1970-01-01
相关资源
最近更新 更多