Подтвердить что ты не робот

Пример реализации "TryParse" или "TryGetValue"

Можете ли вы привести пример реализации шаблона .NET try?

Edit:

Я не имею в виду оператор "try-catch", я имею в виду шаблоны попыток, например те, которые используются в методах TryParse() и TryGetObjectByKey().

В частности, что делать с поднятыми исключениями в пользовательских методах шаблона try. Должен ли я его регистрировать, я должен игнорировать это. "Кто-нибудь знает, что такое практика с этими методами?

4b9b3361

Ответ 1

Вот пример использования метода TryXxx:

string s = Console.ReadLine();
int x;
if (int.TryParse(s, out x))
{
    Console.WriteLine("You entered the valid integer {0}", x);
}
else
{
    Console.WriteLine("Invalid input!");
}

Вот пример определения метода:

bool TryParse(string s, out int x)  // out parameter for result
{
    if (!allCharactersAreValid(s))
    {
        x = 0;
        return false;
    }

    // More checks...
    // Parse the string...

    x = 42;
    return true;
}

Обработка исключений

Наиболее конкретно, что делать с завышенными исключениями в пользовательских методах шаблона "try"

Ваш метод, вероятно, должен избегать исключения каких-либо исключений - если ваш пользователь хотел исключений, он использовал бы версию, отличную от Try. Поэтому вы должны избегать вызова методов, которые могут бросаться при реализации вашего TryXxx. Однако некоторые исключения неизбежны и могут быть выброшены из вашего контроля - например, OutOfMemoryException, StackOverflowException и т.д.... Вы ничего не можете сделать по этому поводу, и вы не должны пытаться поймать эти исключения, просто позвольте им распространяться вызывающему абоненту. Не проглатывайте их, не регистрируйте их - что ответственность вызывающего.

Примером этого является Dictionary<TKey, TValue>.TryGetValue, когда ключевой объект, предоставленный этому методу, генерирует исключение при вызове GetHashCode. Затем полученное исключение не попадает внутрь метода TryGetValue - вызывающий объект увидит исключение. Этот код демонстрирует это:

using System;
using System.Collections.Generic;

class Foo
{
    public override int GetHashCode()
    {
        throw new NotImplementedException();
    }
}

class Program
{
    public static void Main()
    {
        Dictionary<object, object> d = new Dictionary<object, object>();
        d["bar"] = 42;

        object s;
        Foo foo = new Foo();
        if (d.TryGetValue(foo, out s))   // results in NotImplementedException
        {
            Console.WriteLine("found");
        }
    }
}

Ответ 2

Я ожидаю, что реализация будет очень похожа на "бросающую" версию в каждом случае - кроме случаев, когда в металической версии есть "throw new FormatException", там "return false"... и в конце пути успеха, есть назначение выходного параметра и "return true".

В какой-то степени вы можете моделировать металическую версию из не бросающей версии (хотя с точки зрения производительности вы не можете сделать обратное) - вы можете просто вызвать TryParse и выбросить исключение, если оно вернет false. Однако это означает, что исключение не будет содержать подробностей о том, почему синтаксический анализ не удался.

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

Ответ 3

Я предполагаю, что вы имеете в виду что-то вроде метода Int32.TryParse или Dictionary<TKey, TValue>.TryGetValue. Этот метод существует для уклонения от дорогостоящего исключения, и пусть вызывающий может узнать об ошибке другими способами - логическое значение возврата в этом случае.