对象初始化可以简化

Wha*_*int 43 c# initialization

使用我的代码,我得到3条消息,object initialization can be simplified并且在我不断增长的知识渴望(和我的强迫症)中,我想"修复"我的代码,以便这些消息不会出现.我知道我可以设置它,所以这些消息不会出现,但我仍然会在我的脑海里,他们在背景中并不适合我.如果有人能指出如何"简化初始化"那将是很好的,所以我可以提高我的技能.如果需要更多代码,请告诉我,我可以添加它.

第一名:

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

第二:

DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1); //this line
Run Code Online (Sandbox Code Playgroud)

我怀疑它的treenodes是因为我给了他们相同的名字,但我尝试更改名称但它并没有什么区别.

第三:

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

Ton*_*ham 53

虽然之前的所有建议都很好,但我会添加第三种方法.关闭这些警告并忽略它们.虽然我很欣赏微软试图让每个人都能有效而整洁地编写代码,但在我看来,这并不是一个好的建议,它实际上会产生难以阅读和编辑的代码.

首先,这实质上将对象初始化转换为单行代码,并且任何错误都是这样报告的.如果您将20位数据加载到对象中,您将在第一行显示错误,而不会告知哪个属性有错误.调试无效,因为您将整个代码块显示为错误.

其次,如果您将来需要扩展代码并为特定属性添加其他代码,您现在需要在单独的代码中执行此操作.这增加了碎片并分离了相关的代码(也许,这是有争议的).

这两个问题似乎都是非常小的问题,但警告提示修复也是一件非常小的事情.为了包含初始化,您已经使代码更难以调试和修改.在我看来,这是一个糟糕的交易.

您可以通过右键单击警告并选择"抑制"来禁用警告,或者转到工具>选项>文本编辑器> C#>代码样式>常规>首选对象初始值设定项>并将警告设置为无,或将"首选项"设置为没有.

  • 我不期待投票,但我想留下这个,因为它为我提出了第一个结果:) (9认同)
  • 我在问题中提到我不想关闭消息 (2认同)
  • 谢谢,这很有帮助。我最终将“首选项”更改为“否”,而不是将“严重性”更改为“建议”,以便在代码与默认设置相反时获得建议。 (2认同)
  • @WhatsThePoint,感谢您添加这个问题,我理解您尝试清除这些消息的冲动,这也是我写这篇文章的原因。值得庆幸的是,托尼让我明白了。他的评论非常有效且重要。我建议对抗强迫症并关闭消息。 (2认同)

ear*_*loc 44

1

之前:

TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);
node.Tag = drive;
Run Code Online (Sandbox Code Playgroud)

后:

var node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage) {
    Tag = drive
};
Run Code Online (Sandbox Code Playgroud)

第2

之前:

DirectoryInfo di = new DirectoryInfo(dir);
TreeNode node = new TreeNode(di.Name, 0, 1); //this line
Run Code Online (Sandbox Code Playgroud)

之后:

var node = new TreeNode((new DirectoryInfo(dir)).Name, 0, 1);
Run Code Online (Sandbox Code Playgroud)

第3

之前:

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

后:

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

3(带字符串插值):

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

顺便说一句:每当出现这种消息时,尝试将光标放在该行上并点击Ctrl+ .(或点击出现的灯泡) - 这会打开"快速修复/快速重构"

进一步阅读var(它真的不是邪恶的)和一些关于Object和Collection Initializers的文档

  • 不,绝对不是,继续阅读链接文章,这只是一个"捷径".(尝试将鼠标放在var-declaration上,这将为您提供确切的推断类型.var!= variant !!!! :) (7认同)
  • 仅仅是我还是这些“简化”示例中的某些实际上难于阅读?这不是我从Visual Studio中看到的最有用的建议 (6认同)
  • 谢谢,但是我不确定为什么`var`比实际给出它的类型更简单,因为据我了解,`var`用于各种类型? (3认同)

Chr*_*ani 7

我对此代码有类似的问题:

        Customer oCust = new Customer();
        oCust.Address = txtAddress.Text;
        oCust.City = txtCity.Text;
        oCust.State = txtState.Text;
Run Code Online (Sandbox Code Playgroud)

并使用此代码解决了它:

        Customer oCust = new Customer()
        {
           Address = txtAddress.Text,
           City = txtCity.Text,
           State = txtState.Text
        };
Run Code Online (Sandbox Code Playgroud)

Sooo ...关闭警告信息(IDE0017)(在VS 2017中):
单击Tools选项卡.然后转到Options...
Then | TextEditor | C#| CodeStyle | 一般|
Expressoin喜好改变体型对象初始化.


Nic*_*ler 5

我喜欢@tonyenkiducx 的回答,但我觉得似乎应该讨论一些更宏观的想法。

根据我的经验,Visual Studio 提供的重构建议没有帮助。我认为需要考虑的更大问题是代码设计是否正确。在面向对象编程中,一个接一个地设置属性可能会违反封装。这个想法是,在访问/调用任何成员之后,对象应该始终处于有效状态,直到对象被销毁为止。在这种情况下,在设置每个属性后状态应该是有效的。适当的封装将导致整体改进的软件应用程序,因为您正在增加其内聚性。

如果违反了封装,这些object initialization can be simplified消息可能有助于检测代码中可以使用Creational Pattern 的点

  • 抽象工厂模式
  • 建造者模式
  • 工厂方法模式
  • 原型模式

这使我们能够解决@tonyenkiducx提出的问题:

首先,这基本上将对象初始化变成了一行代码,并且任何错误都会被报告。如果您将 20 位数据加载到一个对象中,您将在第一行显示错误,而不会告知哪个属性出错。调试将无济于事,因为您将整个代码块显示为错误。

其次,如果您将来需要扩展代码并为特定属性添加其他代码,您现在需要在单独的代码中执行此操作。这增加了碎片并分离了相关的代码位(也许,这是有争议的)。

因此,我建议您考虑使用创建模式,而不是在对象被消耗时内联实例化(这是 Visual Studio 经常建议的)。这可能不会删除简化消息,但在这一点上,您已经深思熟虑地考虑了该消息标志并且可以安全地取消它。