C# 在C中处理集合中找不到项的优雅方法#

C# 在C中处理集合中找不到项的优雅方法#,c#,C#,我有以下情况: 我有一个foreach循环,它在集合中循环,如果找到一个项(基于下面的示例中的条件),它将返回该项 如果不是的话,处理这个异常最优雅的方式是什么。我有一个新的notimplementedexception,但我认为有一个更优雅的方法 代码是: foreach (SPContentType type in sPContentTypeCollection) { if (type.Name == contentTypeName)

我有以下情况:

  • 我有一个foreach循环,它在集合中循环,如果找到一个项(基于下面的示例中的条件),它将返回该项 如果不是的话,处理这个异常最优雅的方式是什么。我有一个新的notimplementedexception,但我认为有一个更优雅的方法

    代码是:

     foreach (SPContentType type in sPContentTypeCollection)
                {
                    if (type.Name == contentTypeName)
                    {
                        return type; 
                    }
                }
    
     throw new NotImplementedException(); 
    

    正如您所看到的,这不是我所说的可读代码。我怎样才能让下一个人更容易维护。另一方面,从技术角度来看,它做了它应该做的事情。

    未实现异常绝对是错误的异常。我宁愿抛出一个自定义异常,例如ElementNotFoundInCollection


    另一种方法是只返回null。然后,您必须在调用端检查返回的对象是否为null。

    这实际上取决于这是预期的还是例外情况

    如果与之比较的项被传递给一个方法,并且集合中确实应该始终存在一个匹配项,那么我会抛出一个
    ArgumentOutOfRangeException
    异常


    如果预期有时找不到匹配的项,我只会返回
    null
    ,以指示未找到请求的项。

    那么
    NotImplementedException
    肯定不合适,因为您已经实现了该方法。。。但是你应该抛出什么样的异常呢?老实说,这取决于上下文

    有时返回null表示缺少值是合适的。其他时候,抛出一个异常是可以的——可能是一个例子。如果这种情况表示某种描述的错误,而不是调用方期望发生的完全合理的情况,则应该抛出异常

    至于代码的其余部分。。。如果您使用的是.NET 3.5,您可以使用LINQ:

    return sPContentTypeCollection.Cast<SPContentType>()
                                  .First(type => type.Name == contentTypeName);
    

    我同意罗夫的观点,不实施是错误的。如果您不想定义自己的异常类,它非常接近


    返回
    null
    也是一个选项。

    好吧,看看.NET framework本身在自己的类中是如何处理这种情况的可能是值得的。例如,以
    字典
    为例。有两种方法可以从字典中获取值:

  • myDic[key]

    • 优点:短小;可以分配给(因此可以使用
      ++
      和类似运算符)
    • 缺点:如果密钥不存在,则抛出
      KeyNotFoundException
  • myDic.TryGetValue(输入、输出值)

    • 优点:如果找不到键,则不会抛出(但返回
      false
    • 缺点:只能获取值,不能设置
  • 因此,如果您只需要获取一个值,并且不想抛出异常,那么第二个显然更可取

    因此,在您的情况下,类似地编写函数:

    public bool TryGetType(string contentTypeName, out SPContentType result)
    {
        foreach (SPContentType type in sPContentTypeCollection)
        {
            if (type.Name == contentTypeName)
            {
                result = type;
                return true;
            }
        }
        result = default(SPContentType);
        return false;
    }
    

    我猜,我问的问题不对。我所关心的是在工作完成部分之后直接进行“悬挂”投掷。在那里进行一次抛出几乎是错误的(不管异常类型如何)。如果代码达到这一点。。。一定是出了什么事。这是可以接受的,还是不好的做法?@JL:在我看来,完全可以接受。当然,如果可能的话,首先使用LINQ会更好。如果你觉得不清楚它为什么会出现,你可以随时使用注释——但我希望方法本身的文档能够让它更清楚。我喜欢让调用方决定结果的真正含义。如果100%的情况下这是一件非常糟糕的事情,那么继续并抛出一个异常。否则,让调用方决定null结果是否需要抛出。如果你找不到你的类型会有多致命?如果在try..catch或null处理之间进行选择,我将采用null处理。然而,如果您需要为外部处理冒泡出异常,那么您就束手无策了……您不能将Linq直接用于SPContentTypeCollection。。您需要先使用.Cast()。@JohnFouhy:添加,谢谢。我很惊讶当时OP没有提到这件事。
    public bool TryGetType(string contentTypeName, out SPContentType result)
    {
        foreach (SPContentType type in sPContentTypeCollection)
        {
            if (type.Name == contentTypeName)
            {
                result = type;
                return true;
            }
        }
        result = default(SPContentType);
        return false;
    }