2016-04-05 16 views
2

私はこの機能を共有するのに恥ずかしいですが、私はそれを解き放つのに役立つ必要があります。私はこれをずっと前から非常に単純な使い方で書いていましたが、それは制御不能になってしまい、正しく処理する方法がわかりません。多くのオプションパラメータの処理

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 

基本的には、この関数に文字列を渡します。[name] [keyword]などは、他のものに置き換えられます。ときには、データを渡す必要がある場合もあります。問題が始まる場所です。私はこれらを同じ機能で使いたかったのですが、私は今、多くのパラメータへの道があります。私は関数の1回の呼び出しでこれらのパラメータをすべて使用することはありません。時間が経つにつれて1トン増やすつもりです。

このような処理を改善するためのアドバイスはありますか?私はこの機能を分断して、個々の基準で置き換えを処理するべきですか?

+3

これらのパラメータで構成されるクラスは、より簡潔にする必要があります – Plutonix

+0

あなたは正しいかもしれません。私は実際にこれをやり直すことを考え、そのアイデアを忘れてしまった。ありがとう! – Josh

+0

@Plutonix私のOPで共有したことを使って、このクラスをどのように構造化するかの大まかな例を書くことができますか?私はこのクラスを使うときに本当に長い文字列を持つように感じていますが、多分私は間違っていると思っています。 – Josh

答えて

1

あなたのやり方はかなり高価です。 Stringsは不変なので、このような行:

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

は...元msgが、その後の作品から、新しいものと交換を作成離れて涙。テキストブロックのレイアウトを指定するためにユーザーが作成する短い文字列を使用して正確な作業を行ったが、長い文字列や多くの置換えの場合はStringBuilderがより高速で効率的になります。 This post is an extreme exampleを使用して1MBの文字列を使用します(SBは5分から86ミリ秒までの時間を短縮しました)。

開始文字列を作成したように思えるので、可能であれば、ゼロから構築して途中でフォーマットしようとします。私は、データまたは他の方法のいくつかについて十分に知らないが、これはあなたのアイデアを与える必要があります:AmountNullable(Of Decimal)(またはAs Decimal?を書くことができる)ことを

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 

注意を。与えられていなければ省略したい場合は、.HasValueを使用してそれを判断できます。これは誤った番号を防ぐことができます:Amount: 0は本当に0を意味するのか、それとも指定されていなかったのでしょうか?それが重要でない限りNullable<T>で気にしないでください。

処理には、条件付きでテキストを追加する方法が示されています。私は旧式のStrConvをNETメソッドに置き換えました。 GetSortedGroupsが何をしているのかわかりませんが、望むのであればどんなグループのリストも並べ替えることができます(Participantsのように)。

このクラスではなくメソッドよりも、行う必要があり、その結果は.ToString()から来ることができ、他の内容に応じて:

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

テストコード:

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() 

結果:

"名前:April Gala Festival; amt = $ 1.23;参加者数:4;参加者名:Hoover、Josh、Ziggy、Zoey;"

私は結果の文字列にいくつかのタイトルと区切り文字があると推測しています。この方法では、各セグメントまたは要素の後に"; "を使用します。

+0

私はそれを手に入れます。私は今私が何をする必要があるかを知っていると思います。いつものように無条件に役立つ。ありがとうございました。 – Josh

関連する問題