Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
34 / 34 / 16
Регистрация: 07.04.2011
Сообщений: 103

Исключения или перечисления

08.11.2016, 15:11. Показов 691. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Давно задавался вопросом, как лучше реализовывать обработку разных ответов от класса.
То есть допустим есть класс, реализующий работу с неким апи, есть несколько методов: авторизация и получении информации о определенном пользователе.
Я вижу несколько вариантов реализации.
1) Вариант на исключениях. Минусы: много классов-исключений.
Кликните здесь для просмотра всего текста
Api:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 class SomeApi
    {
        private readonly string _login;
        private readonly string _password;
        private SomeHttpClient _httpClient;
 
        public SomeApi(string login, string password)
        {
            _login = login;
            _password = password;
            _httpClient = new SomeHttpClient();
        }
 
        public void Login()
        {
            string response = _httpClient.Post("http://somesite.ru/someloginendpoint", _login, _password);
            if (response == "invalid") throw new InvalidCredentialException();
            if (response == "banned") throw new UserIsBannedException();
            if (response == "needActivate") throw new UserIsNotActivatedException();
        }
 
        public UserInfo GetUserInfo(string id)
        {
            string response = _httpClient.Post("http://somesite.ru/somegetuserinfoendpoint", id);
            if (response == "private") throw new UserIsPrivateException(id);
            return new UserInfo(response);
        }
    }
 
    class UserInfo
    {
        public string Name;
        public UserInfo(string name)
        {
            Name = name;
        }
    }
Использование:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 class Program
    {
        static void Main()
        {
            var api = new SomeApi("login", "password");
            try
            {
                api.Login();
                try
                {
                    var userInfo = api.GetUserInfo("someid");
                    Console.WriteLine(userInfo.Name);
                }
                catch (UserIsPrivateException)
                {
                    Console.WriteLine($"user {"someid"} is private");
                }
                catch (SomeNetworkException)
                {
                    Console.WriteLine("network error");
                }
            }
            catch (InvalidCredentialException)
            {
                Console.WriteLine("Incorrect credentials, please try again");
            }
            catch (UserIsBannedException)
            {
                //some code
            }
            catch (UserIsNotActivatedException)
            {
                //some code
            }
            catch (SomeNetworkException)
            {
                Console.WriteLine("network error");
            }
 
 
        }
    }

2) Вариант с использованием перечислений. (немного перемудрил возможно, вообще надо бы еще добавить перечисление GetUserInfoResult с возможными ответами (кроме приватного юзера возможно что то еще может в дальнейшем появиться), но тогда еще третьим параметром ApiRequestResult надо будет передавать какой нибудь object Argument

Кликните здесь для просмотра всего текста
Api:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class SomeApi
    {
        private readonly string _login;
        private readonly string _password;
        private SomeHttpClient _httpClient;
 
        public SomeApi(string login, string password)
        {
            _login = login;
            _password = password;
            _httpClient = new SomeHttpClient();
        }
 
        public ApiRequestResult<LoginResult> Login()
        {
            string response;
            try
            {
                response = _httpClient.Post("http://somesite.ru/someloginendpoint", _login, _password);
            }
            catch (SomeNetworkError)
            {
                return new ApiRequestResult<LoginResult>(false, LoginResult.None);
            }
            if (response == "invalid")return new ApiRequestResult<LoginResult>(true,LoginResult.Invalid);
            if (response == "banned") return new ApiRequestResult<LoginResult>(true,LoginResult.Banned);
            if (response == "needActivate") return new ApiRequestResult<LoginResult>(true, LoginResult.NeedActivate);
            return new ApiRequestResult<LoginResult>(true, LoginResult.Ok);
        }
 
        public ApiRequestResult<UserInfo> GetUserInfo(string id)
        {
            string response;
            try
            {
                response = _httpClient.Post("http://somesite.ru/somegetuserinfoendpoint", id);
            }
            catch (SomeNetworkError)
            {
                return new ApiRequestResult<UserInfo>(false, null);
            }
            if (response == "private") return new ApiRequestResult<UserInfo>(true, UserInfo.Private);
            return new ApiRequestResult<UserInfo>(true, new UserInfo(response));
        }
    }
 
    class ApiRequestResult<T>
    {
        public bool IsOk;
        public T Result;
 
        public ApiRequestResult(bool isOk, T result)
        {
            IsOk = isOk;
            Result = result;
        }
    }
 
    enum LoginResult
    {
        None,
        Ok,
        Invalid,
        Banned,
        NeedActivate
    }
 
    class UserInfo
    {
        public static UserInfo Private = new UserInfo();
        public bool IsPrivate { get; private set; }
        public string Name;
 
        private UserInfo()
        {
            IsPrivate = true;
        }
        public UserInfo(string name)
        {
            Name = name;
        }
    }
Использование:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 class Program
        {
            static void Main()
            {
                var api = new SomeApi("login", "password");
                var loginResult = api.Login();
                if (!loginResult.IsOk)
                {
                    Console.WriteLine("network error");
                    return;
                }
                //process response
                switch (loginResult.Result)
                {
                    case LoginResult.None:
                        break;
                    case LoginResult.Ok:
                        break;
                    case LoginResult.Invalid:
                        break;
                    case LoginResult.Banned:
                        break;
                    case LoginResult.NeedActivate:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
 
            }
        }


Есть еще третий вариант, скомбинировать первые да, то есть исключения, связанные с сетью пробрасывать вызывающей стороне, а ответы просто так возвращать.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.11.2016, 15:11
Ответы с готовыми решениями:

Перечисления или таблицы справочники
Доброго времени суток. Пытаюсь побороть свое скудоумие и уменьшить число пробелов в своих знаниях. Я хочу создать приложение с...

Множество или перечисления
Всем привет, у меня вот такая задача: Необходимо завести объект (множество или перечисления не знаю что правильно) который будет хранить...

Перечисления всех месяцев любого указанного или текущего года
перечисления всех месяцев любого указанного или текущего года конечная неделя которых содержит не больше заданного числа дней

3
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
08.11.2016, 15:22
Цитата Сообщение от Nikolay_W Посмотреть сообщение
третий вариант, скомбинировать первые да
А если определить одно собственное исключение, а в нем уже переменная типа перечисления, которая и будет описывать возникшую проблему. Такой вариант не рассматривали?
0
34 / 34 / 16
Регистрация: 07.04.2011
Сообщений: 103
08.11.2016, 15:24  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
А если определить одно собственное исключение, а в нем уже переменная типа перечисления, которая и будет описывать возникшую проблему. Такой вариант не рассматривали?
Получается, тогда будет одно перечисление на все возможные методы, и значений в нем может быть большое количество. Это нормально?


upd: я понял, вы имели в виду generic переменную. Надо попробовать, выглядит интересно
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
08.11.2016, 15:37
Цитата Сообщение от Nikolay_W Посмотреть сообщение
значений в нем может быть большое количество
А зачем особенно большое? Конечным пользователям вовсе не нужны тонкости. Краткое указание что не так, и хватит. Так что вполне три-пять членов перечисления должно хватить.

Добавлено через 10 минут
Цитата Сообщение от Nikolay_W Посмотреть сообщение
я понял, вы имели в виду
Типа вот такой конструкции.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Text;
 
namespace ConsoleApplication23 {
    class Program {
        static void Main(string[] args) {
            try {
                throw new MyException(Result.NO_NETWORK);
            }
            catch (MyException ex) {
                Console.WriteLine(ex.Result);
            }
            Console.ReadLine();
        }
    }
    public class MyException : Exception {
        public readonly Result Result;
        public MyException(Result r) {
            Result = r;
        }
    }
    public enum Result {
        OK,
        NO_NETWORK,
        GENERIC
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.11.2016, 15:37
Помогаю со студенческими работами здесь

Исключения или проверки?
Приветствую всех. Возникла у меня проблема выбора варианта реализации кода. Либо код будет сделан с использованием выбросов исключений и...

JIT-отладчик или необработанные исключения
Писал код на c++ opengl, запускается нормально, компилится, но после закрытия окна на крестик(успешно) выскакивал jit чтобы откомпилировать...

Вытащить номер или название исключения
Собственно нужно узнать номер или имя исключения. отлавливаю вот так: catch (Exception ex) { } ...

Определить уникальный код или текст исключения
При обработке исключения e свойство e.HResult выдает одно и то же число для разных похожих исключений. Свойство e.Message выдает разный...

Что быстрее, проверка на null, или проверка на тип перечисления в запросе?
вопрос такой. если несколько таблиц. сходных по структуре в запросе. в первой таблице типТовара = перечисление.тратата.набор во...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru