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