C#这个初始化器真的多余吗?
我有以下代码行:
var dmrReceived = new DownloadMessagesReport();
StyleCop和ReSharper建议我删除冗余初始化程序。 但是,如果我用它替换它
DownloadMessagesReport dmrReceived;
当然这会生成一个未设置为对象实例的对象引用吗? 我使用的是.NET 3.5。 你不再需要手动实例化对象吗?
下一行是:
dmrReceived = dc.DownloadNewMessages(param, param2, param3);
值得注意的是, dc
是从WCF服务生成的类。 所以DownloadNewMessages
是一种WCF Web服务方法。
如果它是一个字段,它将自动初始化为其默认值 – 对于引用类型为null 。 但是考虑到var
,我猜它不是,并且你实际上是在你的代码中进一步实例化它,从而丢弃你在这里实例化的值。 您不需要初始化声明它的变量。 如果你想使用var
,那么我建议你在实际使用它的地方声明它。
所以你的代码是
var dmrReceived = new DownloadMessagesReport(); dmrReceived = dc.DownloadNewMessages(param, param2, param3);
第二行不会填充您在第一行中创建的对象,但它会完全替换该对象。 因此不需要第一个赋值(因为第一个对象从未使用过),这就是R#警告的内容。
如果在分配dmrReceived
之前访问dmrReceived
则只会生成对象引用错误。 很多时候,resharper说初始化器冗余的原因是变量将始终在每个可能的执行路径中分配另一个值。
即
DownloadMessagesReport dmrReceived; ... if(condition) { dmrReceived = new DownloadMessagesReport(); } else { throw new Exception("oh no"); } return dmrReceived.SomeProperty;
访问dmrReceived
是代码中第一个dmrReceived
实际需要具有值的位置。 从代码的其余部分可以看出,如果没有为它赋值,就无法获得该代码行,因此,可能已经分配的初始值不会在任何执行路径中使用,因此会冗余。
“你不再需要手动实例化对象吗?”
当然,您需要“手动”实例化对象,编译器如何知道何时或何处实例化它?
一个简单的场景是这样的:
MyType x; if ( EverythingWorkedOut ) x = new MyType(params); else x = null;
如果编译器第一次实例化它,那么在所有代码中它将是冗余的并且开销更大。
不要相信ReSharper或任何其他计算机智能的东西超过你自己的直觉! 你知道他们并不总是对的。
只是旁注,你真的不需要做x = null;
因为它应该是非实例化对象的默认值。
当然这够了吗?
DownloadMessagesReport dmrReceived = dc.DownloadNewMessages(param, param2, param3);
假设这是你的代码:
var dmrReceived = new DownloadMessagesReport(); dmrReceived = dc.DownloadNewMessages(param, param2, param3);
您正在第一行中创建DownloadMessagesReport
的实例。 然后通过为dmrReceived
变量分配从DownloadNewMessages
方法返回的另一个值来抛弃此对象。 第一个new DownloadMessagesReport()
对象是多余的。 您有效地创建了垃圾收集器在某些时候必须清理的垃圾。
这就是ReSharper和StyleCop向您展示警告的原因。
如果你可以在声明变量的同一行中用实际值初始化变量,那么就这样做。