2016-04-05 21 views
2

Bu işlevi paylaşmaktan utanıyorum, ancak bunu temizlemem için yardıma ihtiyacım var. Bunu çok uzun bir süre önce çok basit bir kullanım için yazdım, ama kontrolden çıktı ve nasıl düzgün bir şekilde kullanılacağından emin değilim. başka bir şeyle değiştirilmesi [ad] [anahtar kelime], vb: İsteğe Bağlı Bir Çok Parametreyi Kullanmak

Public Shared Function SetVariables(msg As String, Optional name As String = "", Optional target As String = "", Optional amount As Decimal = 0, Optional cost As String = "0", Optional keyword As String = "", Optional time As String = "", Optional reward As String = "", Optional participantList As String = "", Optional participantCount As Integer = 0, Optional game As String = "", Optional viewers As String = "", Optional followers As String = "", Optional link As String = "", Optional _options As String = "", Optional Year As String = "", Optional Month As String = "", Optional Day As String = "", Optional Hour As String = "", Optional Minute As String = "", Optional grpname As String = "") 
    Dim balance As Decimal 
    Dim holdings As Decimal 
    If name > "" Then 
     If Options.Accounts.ContainsKey(name) Then 
      If Options.Holdings.ContainsKey(Options.Accounts.Item(name)) Then 
       holdings = Options.Holdings.Item(Options.Accounts.Item(name)) 
      End If 
      balance = Options.Accounts.Item(name).Points 
     End If 
    End If 
    msg = msg.Replace("[name]", StrConv(name, VbStrConv.ProperCase)) 
    If holdings > 0 Then 
     msg = msg.Replace("[balance]", balance & "[" & holdings & "]") 
    Else 
     msg = msg.Replace("[balance]", balance) 
    End If 
    msg = msg.Replace("[channel]", Subs.UppercaseFirstLetter(Options.Channel.TrimStart("#"))) 
    msg = msg.Replace("[target]", Subs.UppercaseFirstLetter(target)) 
    msg = msg.Replace("[amount]", amount) 
    msg = msg.Replace("[cost]", cost) 
    msg = msg.Replace("[keyword]", keyword) 
    msg = msg.Replace("[time]", time) 
    msg = msg.Replace("[reward]", reward) 
    msg = msg.Replace("[participantList]", participantList) 
    msg = msg.Replace("[participantCount]", participantCount) 
    msg = msg.Replace("[botname]", Subs.UppercaseFirstLetter(Options.User)) 
    If msg.Contains("[groups]") Then msg = msg.Replace("[groups]", GetSortedGroups(name)) 
    If msg.Contains("[group]") Then msg = msg.Replace("[group]", GetSortedGroups(name, True)) 
    msg = msg.Replace("[game]", StrConv(game, VbStrConv.ProperCase)) 
    msg = msg.Replace("[viewers]", viewers) 
    msg = msg.Replace("[followers]", followers) 
    msg = msg.Replace("[link]", link) 
    msg = msg.Replace("[options]", options.ToUpper) 
    msg = msg.Replace("[years]", Year) 
    msg = msg.Replace("[months]", Month) 
    msg = msg.Replace("[days]", Day) 
    msg = msg.Replace("[hours]", Hour) 
    msg = msg.Replace("[minutes]", Minute) 
    msg = msg.Replace("[grpname]", StrConv(grpname, VbStrConv.ProperCase)) 

    If balance = 1 Or amount = 1 Then 
     msg = msg.Replace("[currency]", Options.PName) 
    Else 
     msg = msg.Replace("[currency]", Options.PNames) 
    End If 
    Return msg 
End Function 

Temelde ben bunlardan birkaç tane içerir, bu işleve bir dize geçer. Bazen verileri de bununla değiştirmek zorundayım, problemin başladığı yer burası. Bunların aynı işlevde olmasını istedim, ama şimdi birçok parametreye varım var. Bu parametrelerin hiçbirini fonksiyonun tek bir çağrısında kullanmam ve zaman geçtikçe daha fazla ton ekleyeceğim.

daha böyle bir şey nasıl ele alınacağı üzerinde herhangi bir tavsiye? Sadece bu işlevi parçalara ayırmalı ve değiştirmeleri tek tek ele almalı mıyım?

+3

Bu paramiklerden oluşan bir sınıf daha özlü hale getirmelidir – Plutonix

+0

Hak olabilirsiniz. Aslında bunu bir süre önce yapmayı düşündüm ve bu fikri unutmuşum. Teşekkürler! – Josh

+0

@Plutonix OP'mde paylaştığım şeyi kullanarak, bu sınıfı nasıl yapılandıracağınıza dair kaba bir örnek yazabiliyor musunuz? Bu dersi kullanırken gerçekten çok uzun bir dizime sahip olacağımı düşünüyorum, fakat belki de yanlış bakıyorum. – Josh

cevap

1

bunu yapıyoruz yolu oldukça pahalıdır. Strings nedenle satır böyle, değişmez şunlardır:

msg = msg.Replace("[followers]", followers) 

... sonra orijinal msg yırtılır parçalara ve değiştirme gelen yeni bir tane oluşturur. Kullanıcı, bir metin bloğunun düzenini belirtmek için oluşturduğu kısa dizelerle yaptığınız şeyi yaptım, ancak StringBuilder, daha uzun dize ve/veya çok sayıda yedekte daha hızlı ve daha verimli olacaktır. Bir 1MB dizgi kullanarak This post is an extreme example (SB 5 dakikadan 86 milisaniyeye kadar süreyi doğradı). Eğer Sıfırdan inşa ve yol boyunca biçimlendirmek çalışacaktı mümkünse başlayan dize, kıyılmış olan inşa gibi

sesler beri. Ben verilerin veya başka yöntemlerden bazıları hakkında yeterli bilmiyorum ama bu size bir fikir verecektir: AmountNullable(Of Decimal) (veya As Decimal? yazılmış olabilir) o

Public Class MessageMaker 
    Public Property Name As String 
    Public Property Target As String 
    Public Property Amount As Nullable(Of Decimal) 
    Public Property Cost As String   ' string? Really? 

    ' illustration 
    Public Property Participants As List(Of String) 
    ' ergo participantCount==Participants.COunt() 

    Public Property GroupName As String 
    ' etc ad nauseum 

    Public Sub New() 
     Participants = New List(Of String) 
    End Sub 

    Public Function GetFormattedMsg() As String 
     Dim sb As New StringBuilder 

     sb.AppendFormat("The Name: {0}; ", Name) 
     ' or...this will only append the name when lengh>0 
     'sb.AppendFormat(If(String.IsNullOrEmpty(Name), "", TitleCase(Name) & "; ")) 

     If Amount.HasValue Then 
      sb.AppendFormat("amt = {0}; ", Amount.Value.ToString("C2")) 
     End If 

     Dim p As String = "" 
     If Participants.Count > 0 Then 
      sb.AppendFormat("Participant Count: {0}; ", Participants.Count) 
      ' convert names to TitleCase, sort 
      p = String.Join(", ", Participants.OrderBy(Function(x) x). 
          Select(Function(j) TitleCase(j))) 

      sb.AppendFormat("Participant Names: {0}; ", p) 
     End If 

     sb.Append(If(String.IsNullOrEmpty(GroupName), "", 
            String.Format("Grp: {0}; ", TitleCase(GroupName)))) 

     Return sb.ToString 

    End Function 

    Private Function TitleCase(str As String) As String 
     Return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower) 
    End Function 

End Class 

Not. Verilmediği sürece atlamak isterseniz, bunu belirlemek için .HasValue'u kullanabilirsiniz. Bu yanıltıcı sayıları engelleyebilir: Amount: 0 gerçekten 0 anlamına gelir veya belirtilmemiş olduğu anlamına gelir. Önemli değilse, Nullable<T> ile uğraşmayın.

GroupName elleçleme koşullu metni nasıl ekleneceğini gösterir. Ayrıca eski moda StrConv bir NET yönteminin yerini aldı. GetSortedGroups'un ne yaptığını bilmiyorum ama eğer istediğiniz herhangi bir grup listesi (Participants için gösterildiği gibi) anında uçabilir.

bu sınıf yapması gereken başka ne bağlı olarak, daha doğrusu yönteminden daha o sonuç .ToString() gelebilir:

Public Overrides Function ToString() As String 
    ' all the code 
    Return msg 
End Function 

Testi Kodu:

Dim mm As New MessageMaker 
mm.Name = "April Gala Festival" 
mm.Amount = 1.23D 
mm.Participants = New List(Of String) From {"ziggy", "zOEy", "HOOveR", "josh"} 

Dim msg = mm.GetFormattedMsg() 
' or 
Dim msg = mm.ToString() 

Sonuç:

"İsim: Nisan Gala Festivali; amt = 1,23 $; Katılımcı Sayısı: 4; Katılımcı İsimleri: Hoover, Josh, Ziggy, Zoey;"

Sonuçta oluşan dizede bazı başlıklar ve sınırlayıcılar olduğunu tahmin ediyorum. Yöntem, her segment veya öğeden sonra "; " kullanır.

+0

Anladım. Sanırım şimdi ne yapmam gerektiğini biliyorum. Koşulsuz olarak her zaman yardımcı olur. Teşekkür ederim. – Josh