С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282

Оптимально ли использовать методы расширения для проверки на null?

15.05.2017, 15:33. Показов 2606. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Коллеги добрый день!
Подскажите, совсем запамятовал..

Вот часто бывает необходимость проверить объект на null и если он равен null
выдать исключение. Можно каждый раз писать конструкцию if ... throw new exception() ...
Но удобнее было бы, скажем, повесить расширение на object.
и в таком случае обращение было бы таким:
C#
1
myobject.ThrowIsNull(message);
Согласитесь это красивее и читаемее. Но что то мне внутренне подсказывает что
пихать в object не стоит... Ну и наверно производительность будет хромать?

Что Вы думаете по этому поводу, стоит ли так делать, и если нет то почему?
Буду очень признателен, спасибо!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.05.2017, 15:33
Ответы с готовыми решениями:

Оптимально ли использовать Count для большого количества записей
Здравствуйте, если у меня много записей в таблице и я использую COUNT это нормально? Можно ли как-либо оптимизировать?

Методы расширения для анимаций
Зачем нужны эти методы расширения в Graph3D? function Sec(Self: integer): real; extensionmethod := Self; // строка 3305 function...

Методы расширения для двумерной матрицы любых типов
Есть методы расширения для целочисленной матрицы. Как сделать (если возможно) их применение для любых типов элементов? public static...

16
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.05.2017, 15:45
Лучший ответ Сообщение было отмечено Dimblch как решение

Решение

Dimblch, во-первых в шарпе на этот случай встроили синтаксис:
C#
1
2
3
4
public Foo(IBar bar)
{
   this.bar = bar ?? throw new ArgumentNullException(nameof(bar));
}
во-вторых есть тулзы вроде Fody или PostSharp, которые как раз генерируют подобные проверки автоматически.

Экстешн писать можно (я так делал, на object вешал, да), но это было до того, как появился синтаксис из примера выше. Так что щас это уже не актуально.

Ну и да, с чего должна проседать производительность от написания метода я не понял.
0
Эксперт .NET
 Аватар для Usaga
14113 / 9330 / 1350
Регистрация: 21.01.2016
Сообщений: 35,057
15.05.2017, 15:45
Dimblch, производительность не пострадает, так как метод расширения это обычный статичный метод. Другое дело, что конкретно такое решение очень плохо: данный метод не имеет отношения к классу object, потому ему там не место. Его нужно вынести в отдельный статичный класс-хелпер.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.05.2017, 15:50
Usaga, но ты ведь не сможешь заиспользовать этот хелпер, не подключив нужный неймспейс. А если подключил, то наверное ты хочешь именно этого функционала, и писать постоянно имя класса-хелпера не очень С другой стороны, с новомодными using static получается даже более идеоматично ThrowIfNull(obj) против obj.ThrowIfNull(). Ну а с третьей стороны, ?? throw решает все проблемы.
0
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
15.05.2017, 16:08  [ТС]
Спасибо парни!
А что если у меня имеет отношение к object?
Т.я. я хочу иметь подобную проверку для любых объектов?
Про тулзы понял, посмотрю. но допустим я их не использую, у меня свой хелпер класс(ы) и
я их подключаю по мере необходимости. Т.е. как считаете такой подход нормальный?

(получается что если в каком либо из классов я этот хелпер не подключил, не указав соответствующий alias,
то object не будет захламляться)

Psilon, по поводу синтаксиса ?? - все равно ведь получается громоздко и все равно пишешь проверку...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.05.2017, 16:18
Dimblch,
C#
1
this.bar = bar ?? throw new ArgumentNullException(nameof(bar));
против
C#
1
2
bar.AssertIsNotNull(nameof(bar)); 
this.bar = bar
- ну да, чутка больше букв. Зато у тебя есть полный контроль и над мессаджем, и над передачей имени аргумента и т.п. Ты можешь бросить произвольный эксешпн, например инвалидоп или налреф и так далее... Большой необходимости в таком хелпере я не вижу. Но например и строчек занимает больше, и можно опечататься в стиле

C#
1
2
3
4
5
6
7
public Foo(IBar bar, IBaz baz)
{
   bar.AssertIsNotNull(nameof(bar)); 
   bar.AssertIsNotNull(nameof(baz)); 
   this.bar = bar;
   this.baz = baz;
}
Видишь опечатку? В случае с ?? такого не произойдет.

Добавлено через 5 минут
Для аналога придется писать GetValueOrThrowIfNull - буковок не сильно меньше, метод нарушает SRP (и валидирует, и возаращет объект), это лишняя зависимость, и у тебя опять же нет контроля над тем, какой эксешпн кидать и с какими параметрами.
1
Эксперт .NET
 Аватар для Usaga
14113 / 9330 / 1350
Регистрация: 21.01.2016
Сообщений: 35,057
15.05.2017, 16:19
Цитата Сообщение от Psilon Посмотреть сообщение
но ты ведь не сможешь заиспользовать этот хелпер, не подключив нужный неймспейс.
Ну так это справедливо и для метода расширения.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.05.2017, 16:22
Типичный пример:
C#
1
2
3
4
5
6
public Foo(IBar bar, IBaz baz, ISomethingElse smthElse)
{
   this.bar = bar ?? throw new ArgumentNullException(nameof(bar));
   this.baz = baz ?? throw new InvalidOperationException(nameof(baz));
   this.smthElse = smthElse ?? throw new MyCustomException(nameof(smthElse), "myanotherCustomParameter", 42, null);
}
Добавлено через 1 минуту
Usaga, я про расширение и говорю. Хелперы без расширений лично я использую очень редко. Если тебе нужен хелпер, то ты подключаешь юзинг и юзаешь, если нет, то ты не захламляешь пространство методов, т.к. он будет показываться в списке доступных, только если ты заюзал юзинг, а значит наверное тебе оно нужно
0
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
15.05.2017, 16:27  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Видишь опечатку? В случае с ?? такого не произойдет.
Psilon, Немножко о разном говоришь... В случае с ?? используешь проверку и присваивание, в случае с оппечаткой
только проверку. Если там сделать с присваиванием, то такое произойдет.
Блин, вот SRP реально нарушает..А так хотелось ведь
0
 Аватар для LeniumSoft
1454 / 847 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
15.05.2017, 17:07
Цитата Сообщение от Psilon Посмотреть сообщение
но ты ведь не сможешь заиспользовать этот хелпер, не подключив нужный неймспейс.
Цитата Сообщение от Usaga Посмотреть сообщение
Ну так это справедливо и для метода расширения.
Описать его в неймспейсе System.

У меня вот такая штука есть(спёр с хабра)
Кликните здесь для просмотра всего текста
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
83
84
85
namespace System
{
    /// <summary>
    ///     Реализация монады Maybe.
    /// </summary>
    public static class Maybe
    {
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o"></param>
        /// <param name="evaluator"></param>
        /// <returns></returns>
        public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
            where TInput : class
            where TResult : class
        {
            if (o == null) return null;
            return evaluator(o);
        }
 
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o"></param>
        /// <param name="evaluator"></param>
        /// <param name="failureValue"></param>
        /// <returns></returns>
        public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator,
            TResult failureValue) where TInput : class
        {
            if (o == null) return failureValue;
            return evaluator(o);
        }
 
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="o"></param>
        /// <returns></returns>
        public static bool ReturnSuccess<TInput>(this TInput o) where TInput : class
        {
            return o != null;
        }
 
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="o"></param>
        /// <param name="evaluator"></param>
        /// <returns></returns>
        public static TInput If<TInput>(this TInput o, Predicate<TInput> evaluator) where TInput : class
        {
            if (o == null) return null;
            return evaluator(o) ? o : null;
        }
 
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="o"></param>
        /// <param name="evaluator"></param>
        /// <returns></returns>
        public static TInput Unless<TInput>(this TInput o, Predicate<TInput> evaluator) where TInput : class
        {
            if (o == null) return null;
            return evaluator(o) ? null : o;
        }
 
        /// <summary>
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="o"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static TInput Do<TInput>(this TInput o, Action<TInput> action) where TInput : class
        {
            if (o == null) return null;
            action(o);
            return o;
        }
    }
}


правда я её тоже не пользуюсь после последний C# правок.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.05.2017, 18:43
LeniumSoft, так наоборот же, это аргумент в то, чтобы иметь его в собственном неймспейсе. Захламлять общую область имен для обжекта (!!) в глобальном скопе это
0
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
16.05.2017, 08:44  [ТС]
LeniumSoft, А что за последние правки?
0
 Аватар для LeniumSoft
1454 / 847 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
16.05.2017, 10:31
Цитата Сообщение от Dimblch Посмотреть сообщение
А что за последние правки?
ну вот эти.
C#
1
bar ?? throw
Проверки всякие облегчились.
Например проверка на null

Было:
C#
1
2
3
4
5
6
7
8
9
public static string Truncate(string value, int length)
{
  string result = value;
  if (value != null)
  {
    result = value.Substring(0, Math.Min(value.Length, length));
  }
  return result;
}
стало:

C#
1
2
3
4
public static string Truncate(string value, int length)
{          
  return value?.Substring(0, Math.Min(value.Length, length));
}
0
28 / 18 / 5
Регистрация: 05.05.2017
Сообщений: 73
16.05.2017, 12:19
Я считаю никакого криминала в расширении с проверкой на null нет. Насчет неймспейсов - можно в глобальном неймспейсе объявить и оно везде будет. Единственное что такое лучше не делать если это какая-то публичная библиотека.
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
16.05.2017, 12:24
Цитата Сообщение от Dimblch Посмотреть сообщение
Согласитесь это красивее и читаемее
а по моему, средства из коробки еще красивее
C#
1
Contract.Requires(message != null, nameof(message));
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,045
Записей в блоге: 1
16.05.2017, 12:41
Цитата Сообщение от jr_ Посмотреть сообщение
Contract
эту "коробку" надо ещё устанавливать.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
16.05.2017, 13:48
jr_, эта коробка еще и содержит тонну багов, потому что основана на рерайтере бинарников. Когда встроят на уровень языка, тогда поговорим

Добавлено через 51 секунду
А еще есть вот такая штука
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.05.2017, 13:48
Помогаю со студенческими работами здесь

Методы для проверки условий
Пишу программу по обработке массивов. Приходится постоянно писать проверку на правильность ввода, чтобы число было не вещественным или не...

Intellisence в Visual Studio 2017 5.8.4 не отображает методы расширения для целочисленных литералов
Intellisence в Visual Studio 2017 5.8.4 не отображает методы расширения для целочисленных литералов. Это недоработка или так и...

Как использовать свободное пространство Д для расширения С
Д был объемом 172 гб я сжал оставив на нём 100 гб, но оставшееся свободное пространство для расширения С не могу использовать

Какую коллекцию оптимально использовать?
Совсем запутался, какую коллекцию оптимально будет использовать в этой задаче: LINQ не использовать. У меня сначала были мысли...

Делегаты. Где и зачем они используются? Как оптимально их использовать?
Здравствуйте. Помогите с делегатами. Где и зачем они используются? Как оптимально их использовать?


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru