例外或If / Else语句

时间:2011-04-19 09:08:17

标签: c# .net exception if-statement

我有一个关于何时使用Exception或If / Else语句的问题。 在我的情况下,我想检查DocumentNode是否是TestNode。当它是TestNode时,我想获得节点。

我在下面为此写了两个可能的解决方案。第一个解决方案认为它是TestNode,否则它会产生异常。第二个解决方案 检查它是否是TestNode,然后它执行大致相同的函数来获取节点。谁能告诉我什么是最好的解决方案?或者在那里 更好的解决方案吗?谢谢,彼得。

*抱歉我的英语不好..

private DocumentNode GetTestNode(IEnumerable<DocumentNode> nodes)
{
    foreach (DocumentNode node in nodes)
    {
        if (node.GetValueProperty().ToString() == "TestValue")
        {
            return node;
        }
    }
    throw new TestNodeNotFoundException("This is not a TestNode");
}

OR: 

private DocumentNode IsTestNode(IEnumerable<DocumentNode> nodes) 
{
    foreach (DocumentNode node in nodes)
    {
        if (node.GetValueProperty().ToString() == "TestValue")
        {
            return true;
        }
    }
    return false;
}

private DocumentNode GetTestNode(IEnumerable<DocumentNode> nodes)
{
    foreach (DocumentNode node in nodes)
    {
        if (node.GetValueProperty().ToString() == "TestValue")
        {
            return node;
        }
    }
}

5 个答案:

答案 0 :(得分:7)

如果可以,更好的解决方案是使用LINQ。如果您想要例外,可以使用:

var node = nodes.Where(n => node.GetPropertyValue().ToString() == "TestValue")
                .First();

(如果只有一个这样的节点,你也可以使用Single。)

如果您不想要例外,请改用FirstOrDefault

var node = nodes.Where(n => node.GetPropertyValue().ToString() == "TestValue")
                .FirstOrDefault();

如果没有TestValue节点,则node将为null。

要测试是否存在测试节点,请使用Any

var isTest = nodes.Where(n => node.GetPropertyValue().ToString() == "TestValue")
                  .Any();

(你的最终方法目前不会编译,因为它可以在不返回的情况下到达终点。)

哪个合适取决于你想要做什么。如果缺少测试节点表明存在错误,则抛出异常是合适的。如果没有,使用null表示非常合理,或者您可以使用TryXXX模式显式返回bool值,同时保存找到的节点(如果有)参数。

答案 1 :(得分:1)

这取决于。没有一个testnode是一个特殊的情况,需要暂停执行该函数并进行错误处理?

如果是,那么 - 是的,使用例外。如果这是一件相当正常的事情,你预计会发生一些事情,那么异常可能不是处理它的方法。

答案 2 :(得分:1)

你现在在.net的土地:)为什么不去Linq方式?在IEnumerable<DocumentNode>上创建一个产生IEnumerable<DocumentNode>的扩展程序?稍后这将允许您在测试节点的子集上使用其他Linq操作

public static IEnumerable<DocumentNode> GetTestNodes(this IEnumerable<DocumentNode> nodes)
{
    return nodes.Where(x => x.GetPropertyValue().ToString() == "TestValue");
}

...
docnodes.GetTestNodes()....

答案 3 :(得分:0)

通常,您的程序应该优雅地处理错误。

当代码遇到无法解决的问题时,应该进行投掷并Exception并立即停止,将错误条件抛到callstack的上方,希望其他人能够从条件中恢复。

答案 4 :(得分:0)

一个明智的经验法则是:例外应该是例外。

抛出或不抛出异常不应该是代码问题,作为逻辑问题。你的背景是什么?如果DocumentNode集合不包含测试节点,它是世界末日吗?如果是这样的话,你能继续处理吗?测试节点是强制性的,除了在某些特殊情况下,它总是被包含在内,而不是,它会抛出异常。

但是,如果测试节点是可选的,或者经常缺失,一般情况下,如果没有测试节点的情况不是那么罕见,那么异常就是一种过度杀伤,因为没有例外。