Исключение или утверждение If / Else - PullRequest
2 голосов
/ 19 апреля 2011

У меня есть вопрос о том, когда использовать оператор 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 ]

7 голосов
/ 19 апреля 2011

Лучшим решением было бы использовать LINQ, если вы можете. Если вы хотите исключение, вы можете использовать:

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

(Вы также можете использовать Single, если должен быть ровно один такой узел.)

Если вы не хотите исключение, используйте FirstOrDefault вместо:

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

Тогда node будет нулевым, если нет узлов TestValue.

Чтобы проверить наличие тестового узла, используйте Any

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

(Ваш последний метод в настоящее время не будет компилироваться, так как он может достичь конца без возврата.)

То, что подходит, действительно зависит от того, что вы пытаетесь сделать. Если отсутствие тестового узла указывает на ошибку, тогда выдается исключение. Если нет, используйте null, чтобы сигнализировать, что это вполне разумно, или вы можете использовать шаблон TryXXX для явного возврата значения bool, сохраняя найденный узел (если есть) в параметре out.

1 голос
/ 19 апреля 2011

Вы сейчас находитесь в .net land :) Почему бы не пойти по пути 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()....
1 голос
/ 19 апреля 2011

Это зависит.Разве наличие тестового узла не является исключительным обстоятельством, требующим остановки выполнения этой функции и обработки ошибок?

Если это так, то - да, используйте исключение.Если это происходит нормально и что вы ожидаете, тогда, вероятно, исключение - не тот способ справиться с этим.

0 голосов
/ 19 апреля 2011

Правильное практическое правило таково: исключения должны быть исключительными.

Бросать или не выбрасывать исключение не должно быть проблемой кода, как проблемой логики.Каков твой контекст?Конец света, если коллекция DocumentNode не содержит тестового узла?Можете ли вы продолжить обработку, если это так?Если тестовый узел является обязательным, и он всегда будет включен, за исключением некоторых исключительных обстоятельств, тогда, да, выдается исключение.

Но если тестовый узел является необязательным или часто отсутствует, в целом, если сценарий, в котором нет тестового узла, не является чем-то необычным, то исключения являются излишним, поскольку ничего исключительного не произошло.

0 голосов
/ 19 апреля 2011

Как правило, ваша программа должна корректно обрабатывать ошибки.

Бросок и Exception должны быть выполнены, когда код столкнулся с непреодолимой проблемой и немедленно остановился, выбрасывая условия ошибки выше стека вызовов в надежде, что кто-то еще сможет восстановиться из условия.1004 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...