Intereting Posts
Сортировка массива строк по длине элемента Считайте начальные нули в Int32 Directory.Delete не работает. Ошибка доступа, но в Windows Explorer это нормально Кодекс, демонстрирующий важность ограниченного региона исполнения Использование ранее сгенерированного открытого / закрытого ключа RSA с инфраструктурой .net Основное регулярное выражение для «общего» номера телефона Управление пользовательскими ролями ASP.NET generic class, как установить тип во время выполнения? Преобразовать строку валюты в десятичную? VSTO 2007: как определить номер страницы и абзаца диапазона? C # – WPF: страtagsи тестирования Unity и ASP.NET WebForms – для этого объекта не задан конструктор без параметров ASP.NET MVC 2 Контроллер TryValidate не проверяет элементы List в модели Почему я не могу использовать пакет System.Net.Http в решении с ссылкой System.Net.Http? Подписка на динамические события и 1 обработчик

Возrotation первого метода, который работает, более элегантным способом?

Недавно я обнаружил, что пишу методы, которые последовательно называют другие методы и устанавливают какое-то значение на основе того, какой метод сначала возвращает соответствующее значение. То, что я делал, это установить значение одним методом, а затем проверить значение, и если это не хорошо, то я проверяю следующий. Вот недавний пример:

private void InitContent() { if (!String.IsNullOrEmpty(Request.QueryString["id"])) { Content = GetContent(Convert.ToInt64(Request.QueryString["id"])); ContentMode = ContentFrom.Query; } if (Content == null && DefaultId != null) { Content = GetContent(DefaultId); ContentMode = ContentFrom.Default; } if (Content == null) ContentMode = ContentFrom.None; } 

Здесь метод GetContent должен возвращать значение null если id отсутствует в базе данных. Это краткий пример, но вы можете себе представить, как это может стать неуклюжим, если будет больше вариантов. Есть лучший способ сделать это?

Я предлагаю вам попробовать какой-то шаблон фабричного дизайна для этого случая. Вы можете абстрагировать процедуру создания контента, зарегистрировав разные создатели. Кроме того, вы можете добавить предпочтение для каждого создателя для своей собственной логики. Кроме того, я предлагаю вам инкапсулировать все данные, связанные с Контентом, так же как class ContentDefinition из другого сообщения.

В общем, вам нужно знать, что между гибкостью и эффективностью всегда существует компромисс. Когда-нибудь ваше первое решение будет достаточно хорошим 🙂

Оператор нулевой коалесценции может иметь семантику, которую вы хотите.

 q = W() ?? X() ?? Y() ?? Z(); 

Это по сути то же самое, что:

 if ((temp = W()) == null && (temp = X()) == null && (temp == Y()) == null) temp = Z(); q = temp; 

То есть q является первым непустым значением W (), X (), Y (), или если все они равны нулю, то Z ().

Вы можете целить столько, сколько хотите.

Точная семантика не совсем такая, как я набросал; правила преобразования типов сложны. См. Спецификацию, если вам нужны точные данные.

Вы могли бы также сделать что-то немного более подлый, в соответствии с этим:

 private Int64? GetContentIdOrNull(string id) { return string.IsNullOrEmpty(id) ? null : (Int64?)Convert.ToInt64(id); } private Int64? GetContentIdOrNull(DefaultIdType id) { return id; } private void InitContent() { // Attempt to get content from multiple sources in order of preference var contentSources = new Dictionary> { { ContentFrom.Query, () => GetContentIdOrNull(Request.QueryString["id"]) }, { ContentFrom.Default, () => GetContentIdOrNull(DefaultId) } }; foreach (var source in contentSources) { var id = source.Value(); if (!id.HasValue) { continue; } Content = GetContent(id.Value); ContentMode = source.Key; if (Content != null) { return; } } // Default ContentMode = ContentFrom.None; } 

Это поможет, если у вас будет много источников, за счет увеличения сложности.

Лично я нахожу, когда у меня много заявлений, которые кажутся разрозненными, пришло время сделать некоторые функции.

 private ContentMode GetContentMode(){ } private Content GetContent(int id){ } private Content GetContent(HttpRequest request){ return GetContent(Convert.ToInt64(request.QueryString["id"])); } private void InitContent(){ ContentMode mode = GetContentMode(); Content = null; switch(mode){ case ContentMode.Query: GetContent(Request); break; case ContentMode.Default: GetContent(DefaultId); break; case ContentMode.None: ... handle none case... break; } } 

Таким образом, вы разделяете свои намерения – первый шаг, определяете режим содержимого. Затем получите контент.

Хорошо, потому что я заметил немного поздно, что вы действительно хотели режим ContentFrom, я сделал все возможное, чтобы придумать перевод вашего образца ниже моего первоначального ответа


В общем, я использую следующую парадигму для таких случаев. Найдите и замените свои конкретные методы здесь и там 🙂

 IEnumerable ValueSources() { yield return _value?? _alternative; yield return SimpleCalculationFromCache(); yield return ComplexCalculation(); yield return PromptUIInputFallback("Please help by entering a value for X:"); } T EffectiveValue { get { return ValueSources().FirstOrDefault(v => v!=null); } } 

Обратите внимание, как теперь вы можете сделать v!=null произвольно «интересным» для ваших целей.

Обратите внимание также, как ленивая оценка гарантирует, что вычисления никогда не выполняются, когда _value или _alternative установлены на «интересные» значения


Вот моя первоначальная попытка поместить ваш образец в эту форму. Обратите внимание, как я добавил довольно много сантехники, чтобы убедиться, что это действительно компилируется в автономный C # exe:

 using System.Collections.Generic; using System.Linq; using System; using T=System.String; namespace X { public class Y { public static void Main(string[]args) { var content = Sources().FirstOrDefault(c => c); // trick: uses operator bool() } internal protected struct Content { public T Value; public ContentFrom Mode; // public static implicit operator bool(Content specimen) { return specimen.Mode!=ContentFrom.None && null!=specimen.Value; } } private static IEnumerable Sources() { // mock var Request = new { QueryString = new [] {"id"}.ToDictionary(a => a) }; if (!String.IsNullOrEmpty(Request.QueryString["id"])) yield return new Content { Value = GetContent(Convert.ToInt64(Request.QueryString["id"])), Mode = ContentFrom.Query }; if (DefaultId != null) yield return new Content { Value = GetContent((long) DefaultId), Mode = ContentFrom.Default }; yield return new Content(); } public enum ContentFrom { None, Query, Default }; internal static T GetContent(long id) { return "dummy"; } internal static readonly long? DefaultId = 42; } } 
 private void InitContent() { Int64? id = !String.IsNullOrEmpty(Request.QueryString["id"]) ? Convert.ToInt64(Request.QueryString["id"]) : null; if (id != null && (Content = GetContent(id)) != null) ContentMode = ContentFrom.Query; else if(DefaultId != null && (Content = GetContent(DefaultId)) != null) ContentMode = ContentFrom.Default; else ContentMode = ContentFrom.None; }