возвращаемое значение в Try Catch с дженериками

#c# #generics #try-catch

#c# #обобщения #try-catch

Вопрос:

У меня возникла проблема с указанием правильного возвращаемого значения в try/catch блоке. Я сценарист начинающего уровня и никогда раньше не использовал дженерики.

Сообщение об ошибке является:

«Требуется объект типа, преобразуемого в T «

Что конкретно мне нужно вернуть в конце моего try/catch ?

 private static T LoadData<T>(string filePath)
{
    try
    {
        return JsonUtility.FromJson<T>(File.ReadAllText(filePath));
    }
    catch(Exception e)
    {
        // Something went wrong, so lets get information about it.
        Debug.Log(e.ToString());
        return ?????;
    }
}
  

Комментарии:

1. Единственная разумная вещь — повторно создать исключение. Или return defau< я рекомендую первое.

2. Я предлагаю повторно создать исключение: throw; вместо любого вида return

Ответ №1:

Это действительно зависит от поведения приложения, которое вы хотите определить. Вы можете заставить его вернуть new T() / default (я бы не советовал этого, поскольку пользователи не могут определить, была ли операция успешной или нет), или вы можете создать исключение на уровень выше, чтобы его можно было обработать в другом месте. Весь смысл try catch заключается в обработке неожиданного специфического поведения, поэтому не стоит перехватывать общие исключения, если у вас нет общего способа обработки этого.

Комментарии:

1. Обратите внимание, что для возврата new T() вам нужно ограничить T наличие конструктора без параметров ( where T:new() )

2. @DStanley Извините, я не имел в виду буквально new T() , в моей голове я предполагал использовать Activator для создания экземпляра объекта, но да, вы правы.

3. Примеры кода из этих двух вариантов были бы полезны.

Ответ №2:

Когда что-то пошло не так, мы не можем просто игнорировать это; если у нас недостаточно информации для принятия решения, лучший вариант — усугубить проблему: возможно, метод верхнего уровня знает, что делать.

Поэтому я предлагаю повторно создать исключение вместо того, чтобы возвращать какое-либо значение:

 private static T LoadData<T>(string filePath)
{
    try
    {
        return JsonUtility.FromJson<T>(File.ReadAllText(filePath));
    }
    catch(Exception e)
    {
        // Something went wrong, so lets get information about it.
        Debug.Log(e.ToString());
        
        // let top level method decide what to do:
        //   1. Do nothing (just ignore the exception)
        //   2. Do something (e.g. change permission) with filePath
        //   3. Try load from some other file
        //   4. Try load from some other source, say RDBMS
        //   5. Use some default value
        //   6. Close the application
        //   7. ....    
        throw;
    }
}
  

Пожалуйста, обратите внимание, что здесь, в LoadData<T> методе, мы не знаем контекста, и именно поэтому мы не можем решить, какой вариант из 1..7 является лучшим