структура потока условной и всеобъемлющей логики c #

#c# #asp.net-mvc-2

#c# #asp.net-mvc-2

Вопрос:

Я работаю над asp.net страница и необходимо вывести html на основе числового значения.

Логика такова:

Если ReferenceCount больше 13, то выведите Div-1:

 Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
  

Если ReferenceCount больше 16, то выведите Div-1 и Div-2:

 Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
Html.RenderPartial("TShirt", Model.tweets.FirstOrDefault());
  

Если количество ссылок больше 17, то выведите Div-1, Div-2 и Div-3:

 Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
Html.RenderPartial("TShirt", Model.tweets.FirstOrDefault());
Html.RenderPartial("Banner", Model.tweets.FirstOrDefault());
  

Если ReferenceCount больше 22, то выведите Div-1 и Div-2, а также Div-3 и Div-4:

 Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
Html.RenderPartial("TShirt", Model.tweets.FirstOrDefault());
Html.RenderPartial("Banner", Model.tweets.FirstOrDefault());
Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
  

и т.д. В общей сложности еще 27 оценок ….

Есть ли у кого-нибудь хорошие идеи, как структурировать этот логический поток максимально эффективно?

Я бы предпочел, чтобы у меня было не так много операторов if, и я рассмотрел оператор Switch, который позволил бы вам пройти различные тесты Case, но, похоже, вы не можете иметь выражения в операторах Case переключателей в C #.

Спасибо, Скотт

Ответ №1:

Если у вас действительно есть этот шаблон, вам следует абстрагировать его во что-то вроде этого:

 class TweetSetting
{
    public int MinReferenceCount { get; protected set; }
    public string ViewName { get; protected set; }

    public TweetSetting(int minReferenceCount, string viewName)
    {
        MinReferenceCount = minReferenceCount;
        ViewName = viewName;
    }
}

…

var settings =
    new[]
    {
        new TweetSetting(13, "Tweet"),
        new TweetSetting(16, "TShirt"),
        new TweetSetting(17, "Banner"),
        new TweetSetting(22, "Tweet")
    };

var referenceCount = …; // whatever

foreach (var setting in settings)
{
    if (referenceCount <= setting.MinReferenceCount)
        break;

    Html.RenderPartial(setting.ViewName, Model.tweets.FirstOrDefault());
}
  

Таким образом, если что-то изменится, вы просто измените settings . Еще лучше: вы могли бы загрузить его из файла настроек, и для модификации вообще не потребовалось бы изменять код.

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

1. Спасибо. Это здорово. Но если есть проблема с сетью, мой Model.tweets может быть нулевым. Как я могу с этим справиться? Есть идеи?

Ответ №2:

Если бы каждый оператор просто добавлял дополнительную строку, то я бы сделал что-то вроде этого

 if (refcount > 13)
    Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
if (refcount > 16)
    Html.RenderPartial("TShirt", Model.tweets.FirstOrDefault());
if (refcount > 17)
    Html.RenderPartial("Banner", Model.tweets.FirstOrDefault());
if (refcount > 22)
    Html.RenderPartial("Tweet", Model.tweets.FirstOrDefault());
  

Таким образом, вы не будете так часто повторяться.

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

1. да, я думаю, что я слишком много думал об этом. Спасибо.

2. Я бы переместил Model.tweets.FirstOrDefault() перед первым условием в переменную, чтобы таким образом вы не оставляли себя уязвимыми для условий гонки. Таким образом, вы не будете так часто повторяться. 🙂

3. Да, спасибо. Я вставил этот пример слишком быстро. На самом деле я бы не стал передавать твиты каждому элементу. Я бы, вероятно, использовал разные классы ViewModel для каждой группы, чтобы я мог легко передавать дополнительные данные.