如何编写包含一些一次性对象的 If 语句
Posted
技术标签:
【中文标题】如何编写包含一些一次性对象的 If 语句【英文标题】:how to write an If statement that has some disposable objects in it 【发布时间】:2015-08-24 20:24:43 【问题描述】:我有以下 C# 代码
iSomeObject.MyPoint(SomeConstants.cpU, 2,
myInterface.MySystem.MyCustomType == OtherConstants.cpProjected ? Constants.cpU : Constants.cpT,
1, ref t1, ref t2, ref t3);
当我运行我的专有分析工具时,它说 myInterface.MySystem 导致资源泄漏。
class MyClass:MyInterface,IDisposable
MyInterface myInterface = new MyClass();
我通过将实例 myInstance 强制转换回 IDisposable 并在其上调用 Dipose() 方法来显式处理它。
现在在 myInterface 上调用 MySystem 属性的 get 方法,其中(MySystem)是 IExampleInterface 类型,进一步实现如下代码:
class ExampleClass:IExampleClass,IDisposable
我不确定在 myInterface 上调用 Dipose() 方法是否也会释放 MySystem 创建的资源,或者我是否也需要显式调用 Dispose() 方法。但是一切都发生在 IF 语句条件中,我不确定如何处理这种情况并让我的代码处理掉所有一次性对象,换句话说,我不确定这种情况下的 C# 语法以及如何处理处理概念在这种情况下。
任何建议将不胜感激。
【问题讨论】:
你能在你的界面上实现 IDisposable 吗? 您可以将IDisposable
添加到MyInterface
吗?然后你就不需要任何类型的转换了,静态分析可以跟随整个事情。
@recursive 另一方面派生自 IDisposable
对实现接口的类添加非常严格的要求 - 可能不适合许多情况。
这是一个遗留代码,我不应该对其进行任何更改。
【参考方案1】:
如果 MySystem 是一个 IDisposable 对象,那么您的类应该在它的 Dispose 实现中处理该对象。
否则,请修复您的静态分析工具。
【讨论】:
MySystem 是 IExampleInterface 类型,由 ExampleClass 和 IDisposable 实现。所以 IExampleInterface 不直接继承 IDisposable ,而是由 ExampleClass 实现,它也实现了 IExampleInterface ,如本评论前面所述。【参考方案2】:我会说你应该把处置放在知道你有MyClass
的代码层。
using(var iSomeObject = new MyClass(...))
// do something
iSomeObject.MyPoint(SomeConstants.cpU, 2,
myInterface.MySystem.MyCustomType == OtherConstants.cpProjected ? Constants.cpU : Constants.cpT,
1, ref t1, ref t2, ref t3);
【讨论】:
是的,实际上我没有显示整个代码,但我已经通过在 iAnotherObject 周围放置一个 using 语句然后将其余代码放在花括号内来执行此操作。但是我需要运行静态分析看看我的工具是否抱怨它了。 iAnotherObject 与 iSomeObject 的关系如下: ISomeobject iSomeObject = (ISomeObject)iAnotherObject;不确定将 iAnother 放在 using 语句中,然后将其余代码放入其中后是否会处理 myInterface.MySystem。 我认为这里没有足够的信息来提供更好的猜测,但我可以这么说。通常,当您避免强制转换时,静态分析效果更好。看看你能不能找到消除演员的方法。【参考方案3】:我不确定你所说的 if 语句是什么意思。如果您在方法/属性/构造函数(无论如何)中使用一次性实例,并且它们不属于类的实例成员,则应在使用后立即将其丢弃。
如果您的类中有实现 IDisposable 的成员,那么您的类也应该实现 IDisposable,并且一旦不再需要您的类的实例(就像实现 IDisposable 的其他任何东西一样),应该立即调用 Dispose。
在与实现 IDisposable 的实例交互时,也总是使用 try/finally 或 using 块。
最后请参阅 Microsoft 的 this write up ,了解使用 IDisposable 的完整详细信息和最佳实践。
public interface IExampleInterface void DoSomething();
public class ExampleClass : IExampleInterface, IDisposable
private bool _switch = true;
public void DoSomething()
// lets use something disposable
if(_switch) // is this what you mean by in an if statement??
var stream = new System.IO.MemoryStream();
try
// do something with stream
finally
stream.Dispose(); // call dispose!
private System.IO.FileStream fs; // class level field
public void Dispose()
// dispose of class fields here that implement IDisposable
if(fs != null)
fs.Dispose();
fs = null;
【讨论】:
我不应该操纵任何现有的 IDisposable 实现,因为它是遗留代码。 @user2913184 从您的描述看来,您是将 IDisposable 接口添加到此“旧”代码中的人。如果您将接口添加到类中,那么您还应该添加该接口的实现。如果这不正确,请提供更清晰的示例。以上是关于如何编写包含一些一次性对象的 If 语句的主要内容,如果未能解决你的问题,请参考以下文章
这是在latex中编写的伪代码,如何使得if和then语句在同一行上,节省空间并看起来美观一些。