Так что я не нашел ничего изящного решения для этого, будь то поиск в googling или во время stackoverflow. Я предполагаю, что у меня есть очень специфическая ситуация в моих руках, так или иначе, вот так:C# - Возвращаемые значения по умолчанию для свойств null, когда родительские свойства этих свойств могут быть или не могут быть нулевыми.
У меня есть структура объекта, с которой у меня нет контроля, потому что я получаю эту структуру из внешнего WS. Это довольно огромный объект с различными уровнями полей и свойств, и эти поля и свойства могут или не могут быть нулевыми на любом уровне. Вы можете думать об этом объекте как анемичной модели, у него нет поведения, просто состояние.
Для целей данного вопроса, я дам вам упрощенный образец, который имитирует мою ситуацию:
Class A
PropB1
PropC11
PropLeaf111
PropC12
PropLeaf112
PropB2
PropC21
PropLeaf211
PropC22
PropLeaf221
Таким образом, на протяжении всего моего кода у меня есть доступ к ряду этих свойств, в разных уровнях, чтобы сделать математику, чтобы рассчитать то, что мне нужно. В основном для каждого типа вычислений, которые я должен выполнить, я должен проверить каждый уровень свойств, которые мне нужны, чтобы проверить, не является ли он нулевым, и в этом случае я бы возвращал (десятичный) 0 или любое другое значение по умолчанию в зависимости от бизнес-логики.
Пример из математики, что я должен сделать с ним:
var value = 0;
if (objClassA.PropB1 != null && objClassA.PropB1.PropC11 != null) {
var leaf = objClassA.PropB1.PropC11.PropLeaf111;
value = leaf.HasValue ? leaf.Value : value;
}
Просто очень, свойства листьев этой структуры всегда будет примитивы или обнуляемых примитивы в этом случае я даю надлежащее лечение , Это «логика», которую я должен делать для каждого свойства, которое мне нужно, и иногда мне приходится использовать некоторые из них. Кроме того, реальная структура намного больше, поэтому количество проверок, которые мне нужно будет сделать, также будет больше для каждого необходимого свойства.
Теперь я придумал несколько идей, ни один из них я думаю, что не является идеальным:
- Создание методов для сбора свойств, где бы абстрактные любые необходимые проверки, или логика, чтобы получить значения по умолчанию. Недостатком является то, что у него, по-моему, был бы достаточно дублированный код, так как проверки и значения по умолчанию были бы похожими для некоторых групп полей.
- Создайте единый общий метод, в котором он получает объект, и функцию lamba, которая получает доступ к требуемому полю. Этот метод попытается выполнить функцию и вернуть ее результат, а в случае исключения NullReferenceException будет возвращено значение по умолчанию. Яркая сторона этого заключается в том, что он действительно общий, мне просто нужно передать lambdas для доступа к свойствам, и метод будет обрабатывать любую проблему. Недостатком этого является то, что я использую try-> catch для управления логикой, что не является целью этого, и код может выглядеть запутанным для других программистов, которые в конечном итоге будут поддерживать его.
- Null Object Pattern, это было бы самое элегантное решение, я думаю. У него были бы все хорошие моменты, если бы это был обычный случай. Но дело в том, что для этой структуры можно предоставить Null Objects. Чтобы дать немного больше контекста, программное обеспечение, над которым я работаю, интегрируется с государственными службами и структура, с которой я работаю, которая находится в спецификациях правительства, имеет некоторые поля, где null имеет некоторый смысл, который отличается от значение по умолчанию, например «0». Кроме того, эта спецификация время от времени меняется, и классы генерируются снова, и для последующей обработки, которую мне нужно было бы сделать для создания Null Objects, также потребуется техническое обслуживание, что для меня немного опасно.
Надеюсь, что я сделал себе достаточно ясно.
Заранее благодарен.
Решение
Это ответ о том, как я решил мою проблему, на основе принятого ответа.
Я совершенно новичок в C#, и такая связь, которая была связана, действительно помогла мне придумать элегантное решение во многих аспектах. У меня все еще есть проблема, которая зависит от того, где выполняется код, он использует .NET 2.0, но я также нашел решение этой проблемы, где я могу несколько определить методы расширения: https://stackoverflow.com/a/707160/649790
И для самого решения я нашел это один из лучших: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Я могу в принципе получить доступ к свойствам таким образом, и просто делать математику:
objClassA.With(o => o.PropB1).With(o => PropC11).Return(o => PropLeaf111, 0);
Для каждого свойства, что мне нужно. Он по-прежнему не просто:
objClassA.PropB1.PropC11.PropLeaf111
конечно, но это гораздо лучше, что любое решение, которое я нашел до сих пор, так как я не был знаком с методами расширения, я действительно многому научился.
Еще раз спасибо.
Обсуждение здесь http://stackoverflow.com/q/2080647/2300730 связано с вашим вопросом, некоторые советы оттуда могут быть полезны – jure
Спасибо, что сообщение обсуждает некоторые аспекты дизайна, которые очень интересны, также я нашел «Закон Деметры», что я не был знаком с – JeanK