web-dev-qa-db-ja.com

オブジェクトの初期化を簡素化できます

私のコードではobject initialization can be simplifiedと言う3つのメッセージが表示されます。そして、知識(およびOCD)に対する渇望の高まりの中で、これらのメッセージが表示されないようにコードを「修正」したいと思います。これらのメッセージが表示されないように設定するだけでよいことはわかっていますが、バックグラウンドでメッセージが表示されていないため、私と一緒に座っていることはできません。 「初期化を単純化する」方法を誰かが指摘できれば、それは素晴らしいことなので、スキルを向上させることができます。さらにコードが必要な場合はお知らせください。追加できます。

1番目:

TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);//issue on this line
node.Tag = drive;

2番目:

DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1); //this line

私はそれらに同じ名前を付けたので、そのツリーノードで疑っていますが、名前を変更しようとしましたが、違いはありませんでした。

番目:

OleDbCommand select = new OleDbCommand();//this line
select.Connection = cnDTC;
select.CommandText = string.Format("SELECT MAX(VERSION_NO) AS MAX_VERSION FROM ({0})", strSQL2);
41
WhatsThePoint

1日

Before

TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);
node.Tag = drive;

後:

var node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage) {
    Tag = drive
};

2nd

Before

DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1); //this line

After

var node = new TreeNode((new DirectoryInfo(dir)).Name, 0, 1);

3番目

前:

OleDbCommand select = new OleDbCommand();//this line
select.Connection = cnDTC;
select.CommandText = string.Format("SELECT MAX(VERSION_NO) AS MAX_VERSION FROM ({0})",
      strSQL2);

後:

var select = new OleDbCommand(
      String.Format("SELECT MAX(VERSION_NO) AS MAX_VERSION FROM ({0})", strSQL2), 
      cnDTC);

3番目(文字列補間あり):

var select = new OleDbCommand($"SELECT MAX(VERSION_NO) AS MAX_VERSION FROM ({strSQL2})", 
      cnDTC);

BTW:この種のメッセージが表示されるたびに、その行にカーソルを置いてヒットする Ctrl+. (または表示される電球をクリック)-「クイックフィックス/クイックリファクタリング」を開きます

var (これは本当に悪ではありませんか????)および オブジェクトとコレクションの初期化子

43
earloc

前の提案もすべて良好ですが、3番目の方法を追加します。これらの警告をオフにして無視します。誰もが効率的かつきちんとコーディングできるようにするというマイクロソフトの試みに感謝していますが、これは私の意見では良い提案ではなく、実際にはコードの読み取りと編集が困難です。

まず、これはオブジェクトの初期化を基本的に1行のコードに変換し、エラーが報告されます。オブジェクトに20ビットのデータがロードされている場合、最初の行にエラーが表示され、どのプロパティがエラーになったかは通知されません。コードブロック全体がエラーとして表示されるため、デバッグは役に立ちません。

第二に、将来コードを拡張し、特定のプロパティにコードを追加する必要がある場合は、別のコードでこれを行う必要があります。これにより、断片化が増加し、関連するコードが分離されます(おそらく、議論の余地があります)。

これらの問題はどちらも非常に小さな問題のように思えるかもしれませんが、警告は修正も非常に小さな問題であることを示唆しています。初期化をブラケットで囲むために、コードのデバッグと変更を難しくしました。これは私の意見では悪いトレードオフです。

警告を右クリックして「抑制」を選択するか、または「ツール」>「オプション」>「テキストエディター」>「C#」>「コードスタイル」>「一般」>「オブジェクト初期化子を優先」の順に選択して警告を無効にするか、設定を「なし」に設定します番号。

50
Tony Cheetham

私はこのコードで同様の問題がありました:

        Customer oCust = new Customer();
        oCust.Address = txtAddress.Text;
        oCust.City = txtCity.Text;
        oCust.State = txtState.Text;

そして、このコードでそれを解決しました:

        Customer oCust = new Customer()
        {
           Address = txtAddress.Text,
           City = txtCity.Text,
           State = txtState.Text
        };

Sooo ...警告メッセージをオフにする(IDE0017)(VS 2017/2019):
クリック Tools タブ。次に下に行きます Options...
次にTextEditor | C#| CodeStyle | General
Under Expressoin preferences change Preference Object Initializer to No

または、環境設定をYesのままにして、重大度を警告から提案に変更することもできます。これで、エラーリストにメッセージとして表示されるようになります。

7
Chris Catignani

私は @ tonyenkiducx answer が好きですが、議論する必要のある大局的なアイデアがあるように感じます。

私の経験から、Visual Studioが提供するリファクタリングの提案は役に立ちません。考慮すべき大きな問題は、コード設計が正しいかどうかです。オブジェクト指向プログラミングでは、プロパティを次々に設定するとがカプセル化に違反します。アイデアは、メンバーがアクセス/呼び出された後、オブジェクトが破棄される瞬間まで、オブジェクトは常に有効な状態でなければならないということです。この場合、状態は各プロパティが設定された後に有効になります。適切にカプセル化すると、その粘着性が向上するため、ソフトウェアアプリケーション全体が改善されます。

object initialization can be simplifiedメッセージは、カプセル化に違反した場合に Creational Pattern を使用できるコード内のポイントを検出するのに役立ちます。

  • 抽象的な工場パターン
  • ビルダーパターン
  • 工場メソッドパターン
  • プロトタイプパターン

これにより、@ tonyenkiducxによって提起された懸念に対処できます。

まず、これはオブジェクトの初期化を基本的に1行のコードに変換し、エラーが報告されます。オブジェクトに20ビットのデータがロードされている場合、最初の行にエラーが表示され、どのプロパティがエラーになったかは通知されません。コードブロック全体がエラーとして表示されるため、デバッグは役に立ちません。

第二に、将来コードを拡張し、特定のプロパティにコードを追加する必要がある場合は、別のコードでこれを行う必要があります。これにより、断片化が増加し、関連するコードが分離されます(おそらく、議論の余地があります)。

そのため、オブジェクトが消費される時点でインスタンス化をインライン化するのではなく、Visual Studioがよく提案するように、作成パターンの使用を検討することをお勧めします。これは単純化メッセージを削除しないかもしれませんが、この時点で、あなたは思慮深くそのメッセージフラグを考慮し、安全にそれを抑制することができます。

4
Nick Miller

コンパイラは、次の構文を使用することを望んでいます。

var select = new OleDbCommand
{
   Connection = cnDTC,
   CommandText = string.Format("SELECT MAX(VERSION_NO) AS MAX_VERSION FROM ({0})", strSQL2)
};

これは3番目のケースです。

2
Serraniel