Упрощение длинных строк кодов

#vb.net

#vb.net

Вопрос:

Я создаю программу, которая рассчитывает ежемесячный счет за электроэнергию на основе использования. Коды не аккуратны и выглядят не очень … лаконично, но это работает. Я попытался использовать массив (еще не изучил это в своем курсе), потому что, когда я искал ответы, массивы обычно были решением проблемы. Однако, когда я использую его в своем коде, он вычисляет только для второго оператора, например, если у меня есть If...Else If , он будет проверять Else If и игнорировать только начальный If .

Я создал еще один проект, похожий на проблему. Как вы увидите ниже, месяц длится только до мая, и я должен довести его до октября…

 Option Strict On
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
       
        Dim marTA, aprTA, mayTA As Single

        Dim mar, apr, may As Decimal

        Decimal.TryParse(TextBox1.Text, mar) : Decimal.TryParse(TextBox2.Text, apr)
        Decimal.TryParse(TextBox3.Text, may)

        Select Case True
            Case mar = 0
                marTA = 3D   (3D * 0.06)
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
            Case mar >= 1 And mar < 201
                marTA = CSng(mar * 0.109)
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
            Case mar >= 201 And mar < 301
                marTA = CSng((200 * 0.109)   ((mar - 200) * 0.153))
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
            Case mar >= 301 And mar < 601
                marTA = CSng((200 * 0.109)   (100 * 0.153)   ((mar - 300) * 0.172))
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
            Case mar >= 601 And mar < 901
                marTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   ((mar - 600) * 0.182))
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
            Case mar >= 901
                marTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   (300 * 0.182)   ((mar - 900) * 0.215))
                TextBox4.Text = marTA.ToString("C2").Replace("$", "RM ")
        End Select

        Select Case True
            Case apr = 0
                aprTA = 3   (3 * 0.06)
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
            Case apr >= 1 And apr < 201
                aprTA = CSng(apr * 0.109)
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
            Case apr >= 201 And apr < 301
                aprTA = CSng((200 * 0.109)   ((apr - 200) * 0.153))
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
            Case apr >= 301 And apr < 601
                aprTA = CSng((200 * 0.109)   (100 * 0.153)   ((apr - 300) * 0.172))
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
            Case apr >= 601 And apr < 901
                aprTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   ((apr - 600) * 0.182))
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
            Case apr >= 901
                aprTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   (300 * 0.182)   ((apr - 900) * 0.215))
                TextBox4.Text = aprTA.ToString("C2").Replace("$", "RM ")
        End Select

        Select Case True
            Case may = 0
                mayTA = 3   (3 * 0.06)
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
            Case may >= 1 And may < 201
                mayTA = CSng(may * 0.109)
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
            Case may >= 201 And may < 301
                mayTA = CSng((200 * 0.109)   ((may - 200) * 0.153))
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
            Case may >= 301 And may < 601
                mayTA = CSng((200 * 0.109)   (100 * 0.153)   ((may - 300) * 0.172))
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
            Case may >= 601 And may < 901
                mayTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   ((may - 600) * 0.182))
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
            Case may >= 901
                mayTA = CSng((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   (300 * 0.182)   ((may - 900) * 0.215))
                TextBox4.Text = mayTA.ToString("C2").Replace("$", "RM ")
        End Select
    End Sub
End Class
  

Проектный вид:

Проектный вид

Ответ №1:

В программировании есть аббревиатура DRY. Это означает «Не повторяйся». Для этого есть несколько причин…

  1. Легче отлаживать.
  2. Легче изменить — только одно место вместо нескольких.
  3. Легче читать и понимать.
  4. Меньше подвержен ошибкам. Если вы попытаетесь написать один и тот же код несколько раз, вы допустите ошибку при переписывании.

Есть несколько способов добиться DRY. Одним из них является перенос повторяющегося кода в отдельную функцию. Смотрите GetUsageCharge пример этого.

Другой способ — создать коллекцию похожих объектов. Затем используйте цикл, чтобы применить повторяющийся код к каждому элементу в коллекции. Смотрите TextBoxes и For Each .

 Private Function GetUsageCharge(usage As Integer) As Decimal
    Select Case usage
        Case 0
            Return CDec(3   (3 * 0.06))
        Case 1 To 200
            Return CDec(usage * 0.109)
        Case 201 To 300
            Return CDec((200 * 0.109)   ((usage - 200) * 0.153))
        Case 301 To 600
            Return CDec((200 * 0.109)   (100 * 0.153)   ((usage - 300) * 0.172))
        Case 601 To 900
            Return CDec((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   ((usage - 600) * 0.182))
        Case >= 901
            Return CDec((200 * 0.109)   (100 * 0.153)   (300 * 0.172)   (300 * 0.182)   ((usage - 900) * 0.215))
    End Select
    Return 0
End Function

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim TotalCost As Decimal
    Dim usage As Integer
    Dim TextBoxes As New List(Of TextBox) From {TextBox1, TextBox2, TextBox3}
    For Each tb In TextBoxes
        If Integer.TryParse(tb.Text, usage) Then
            TotalCost  = GetUsageCharge(usage)
        End If
    Next
    TextBox4.Text = TotalCost.ToString("C2").Replace("$", "RM ")
End Sub
  

Как вы можете видеть, этот код намного проще, меньше переменных и т. Д.

Примечание: вы можете избавиться от .Replace("$", "RM ") , если добавите…

 CultureInfo.DefaultThreadCurrentCulture = New CultureInfo("ms-MY")
  

в Form.Load

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

1. Это работает чудесно! Однако есть ошибка — общая стоимость будет постоянно увеличиваться, если пользователь продолжает нажимать на кнопку, отсюда и мои беспорядочные коды. Именно поэтому я разделяю их, чтобы избежать этой проблемы, но это уже другой вопрос, и с этим можно разобраться. Спасибо @Mary

2. TotalCost — это локальная переменная, которая начинается с 0 при каждом нажатии кнопки.

3. Боже мой, я тупой.. Я объявляю это как Public потому, что у меня есть еще одно групповое поле для суммирования общей стоимости за каждый месяц, а также для добавления их в список для печати квитанции. Прошу прощения, моя вина.