4

私は自分のコードでFxCopコンプライアンスを改善しようとしていますが(初めて)、倫理的な問題に少し立ち往生しています。GetText()リモートサーバーから文字列を返すメソッドがありますが、特定の状況で例外をスローする可能性があります。TryGetText(ByRef text As String)そのため、呼び出しが成功したかどうかを示すブール値を返すメソッドもあります。trueの場合、戻り値はテキスト変数に割り当てられます。

Microsoftでさえもそうしていることを考えると、この構造は完全に受け入れられると思いました(例Integer.TryParse)。FxCopは、「あなたは参照で通り過ぎてはならない!」と口述して、私を怒らせています。

この警告を回避するために(そしてそれらのかなりの数があります)、パラメーターをStringBuilderに置き換えました。しかし、現在は準拠しているにもかかわらず、コードが実際に改善されたとは思いません。

前:

    Public Function TryGetText(ByRef text As String) As Boolean
        Dim command As New GetTextCommand(Me)
        Dim result As CommandResult = ProcessCommand(command, True)
        If result.CommandStatus <> Constants.Status.Failed Then
            text = result.Text
            Return True
        Else
            Return False
        End If
    End Function

後:

    Public Function TryGetText(builder As Text.StringBuilder) As Boolean
        Dim command As New GetTextCommand(Me)
        Dim result As CommandResult = ProcessCommand(command, True)
        If result.CommandStatus <> Constants.Status.Failed Then
            builder.Clear()
            builder.Length = result.Text.Length
            builder.Append(result.Text)
            Return True
        Else
            Return False
        End If
    End Function

これはByRefの許容できる使用法ですか、それともstringbuilderの代替手段を使用する必要がありますか?この構成を使用するすべてのメソッドで、この警告を抑制することにあまり満足していません。stringbuilderバリアントがコードの使いやすさを改善したようにも感じません。

4

4 に答える 4

2

それはおそらくの良い使い方なByRefので、その場合の例外を追加する傾向があります。Visual Studioのコード分析機能を使用している場合は、次の属性をメソッドに追加するだけです。

<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#")> _
Public Function TryGetText(ByRef text As String) As Boolean
于 2012-06-15T19:23:40.523 に答える
2

TryActionメソッドは、スレッドセーフクラスなどを作成するときに非常に便利です。これは、テストとアクションの2つのステップを1つのアトミック操作に結合します。Microsoftは、Concurrentコレクションクラスでこれを多用しています。例:http://msdn.microsoft.com/en-us/library/dd287191.aspx#Y0

ですから、「あなたは参照によって通過してはならない」という包括的な声明だと思います。すべての場合において福音と見なされるべきではありません。正当な用途があります。特定のケースでは、ByRefはStringBuilderバージョンよりもはるかに不器用ではないようです。しかし、現在falseを返している場合にnull / Nothingを返す単純なstring GetText()ものが同等である場合、それが最善のように思われます。

于 2012-06-15T19:28:29.023 に答える
0

まあ、私は誰もがあまりにも多くのbyrefを嫌っていると思います。2つはすでに多すぎます。あなたの場合、多くの方法があり、それらはすべて同じパターンに従いますが、実際の問題のようには聞こえません。MicrosoftのTry*メソッドのパターンに固執しないオプションがあります。

ブール値の代わりに、成功した場合は文字列を返し、失敗した場合はNothing / Emptyを返しませんか?次に、String.IsNullOrEmpty(resultText)を使用してTryGetText出力をテストできます。

確かに、それはより多くのコードですが、それは警告を解決します(それが本当にあなたが求めているものである場合)。

于 2012-06-15T19:24:33.643 に答える
0

メソッドを機能的なスタイルで使用しようとすると、参照による受け渡しが複雑になります。null許容型、タプル、または独自のOption型の使用を検討することもできます。

私はVBにあまり詳しくないので、ここにC#の例を示します。

struct Option<T> {
   public bool ContainsElement { get; private set; }
   private T element;
   public T Element {
      get {
         if (!ContainsElement) throw new NoElementException ();
         return element;
      }
      set {
         element = value;
         ContainsElement = true;
      }
   }
   public T GetElementOrDefault (T defaultValue) {
      return ContainsElement ? element : defaultValue;
   }
}

Option<string> GetText () {
   ...
}
于 2012-06-15T19:40:47.483 に答える