Foo f = null; try { f = new Foo(); Foo result = f; f = null; return result; } finally { if (f != null) { f.dispose(); } }
有点冗长,但它有效,这是有道理的.但是如何将该模式应用于链式构造函数,如下所示:
public HomeController ( IDataRepository db ) { this.repo = db ?? new sqlDataRepository(); } public HomeController ( ) : this(new sqlDataRepository()) { }
此代码抛出两个CA2000警告,每个构造函数一个.第一个我可以摆脱使用临时变量模式.这很烦人,因为在构建之后,但是在它被分配到成员字段之前,本地没有任何方式让它超出范围,之后会被清除.所以我不知道CA的问题是什么,但至少我知道如何解决它.
但是,据我所知,没有任何替代方法来编写第二个构造函数调用来引入try / finally.分配给的字段是只读的,因此必须在构造函数中设置.并且C#不会让你在构造函数体之前的任何地方调用链式构造函数.而且,在这两个中,第二个警告实际上是更合法的 – 对链式构造函数的调用可以(理论上,如果它做了任何实际工作)抛出异常并使新构造的参数不被置换.
当然,我总是可以压制这个消息(CA2000似乎需要很多),但如果有一种消除问题的实际方法,我宁愿这样做.
解决方法
public HomeController(IDataRepository db) { this.repo = db ?? new sqlDataRepository(); } public HomeController() : this(null) { }
显然,如果你的第一个构造函数不接受null参数值,这将无法正常工作.如果是这种情况,并且您完全同意只在一个地方设置相应字段的想法,您仍然可以选择避免使用CA2000,例如调用稍微更智能的私有构造函数.例如.:
public HomeController(IDataRepository db) : this(() => db,false) { if (db == null) { throw new ArgumentNullException("db"); } } public HomeController() : this(() => new sqlDataRepository(),true) { } private HomeController(Func<IDataRepository> repositoryRetriever,bool dispoSEOnFailure) { IDataRepository repository = repositoryRetriever.Invoke(); try { this.repo = repository; } catch { if (dispoSEOnFailure) { repository.dispose(); } throw; } }
就个人而言,我认为以上是非常讨厌的黑客,特别是考虑到它涉及增加代码复杂性和运行时异常的机会,以避免一开始就不是非常严重的潜在问题.我的建议是简单地忽略此类潜在的CA2000违规,除非以下两种情况都成立:
>在对象的实例化和将其分配给字段的方法的结尾之间存在非崩溃异常的可能性.>未能处理孤立实例的后果相当严重(例如:保持文件锁定).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。