对象初始化可以简化

时间:2017-04-25 09:01:33

标签: 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;

第二

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

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

第三

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

5 个答案:

答案 0 :(得分:44)

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

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

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

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

您可以通过右键单击警告并选择"禁止"或转到工具>来禁用警告。选项>文本编辑器> C#>代码风格>一般>首选对象初始化器>并将警告设置为“无”,或将“首选项”设置为“否”。

答案 1 :(得分:42)

第一

<强>之前

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
};

第二

<强>之前

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

之后

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

第三

<强>之前:

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 + (或单击出现灯泡) - 打开&#34;快速修复/快速重构&#34;

进一步阅读var(这真的不是邪恶的)和 有关Object and Collection Initializers

的更多文档

答案 2 :(得分:6)

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

        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中):
单击工具选项卡。然后转到选项......
然后 | TextEditor | C#| CodeStyle |一般|
Expressoin偏好设置下,将首选对象初始值设定项更改为

答案 3 :(得分:3)

我喜欢@tonyenkiducx answer,但我觉得好像有一些应该讨论的更大的想法。

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

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

  • 抽象工厂模式
  • 构建器模式
  • 工厂方法模式
  • 原型模式

这使我们能够解决 @tonyenkiducx 带来的问题:

  

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

     

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

因此,我建议您考虑使用创建模式,而不是在对象被消耗的点处内联实例化,这是Visual Studio经常建议的。这可能不会删除简化消息,但此时,您已仔细考虑过该消息标记并可以安全地抑制它。

答案 4 :(得分:2)

我猜这些消息只是希望你使用floowing语法:

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

这是第3个案例。