Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在另一个方法中正确处理本地创建的对象?_C#_Idisposable - Fatal编程技术网

C# 如何在另一个方法中正确处理本地创建的对象?

C# 如何在另一个方法中正确处理本地创建的对象?,c#,idisposable,C#,Idisposable,因此,我有一个实现IDisposable的类,还有几个方法(在另一个类中)遵循以下模式: public void SomeMethod() { DisposableObject disposableObject = new DisposableObject(); // Do some stuff with the object SomeOtherMethod(disposableObject); disposableObject.Dispose(); } 虽

因此,我有一个实现IDisposable的类,还有几个方法(在另一个类中)遵循以下模式:

public void SomeMethod()
{
    DisposableObject disposableObject = new DisposableObject();

    // Do some stuff with the object

    SomeOtherMethod(disposableObject);
    disposableObject.Dispose();
}
虽然所有这些方法都做了不同的事情,但它们最后都调用了
SomeOtherMethod
,这会在不再需要一次性对象之前对其做更多的事情。 当我移动
disposableObject.Dispose()时
进入
SomeOtherMethod
,Visual Studio给我一条消息说: “使用建议的dispose模式确保在所有路径上释放由‘new DisposableObject()’创建的对象:使用语句/声明或try/finally”

无论是否使用
ref
关键字将一次性对象传递给
SomeOtherMethod
,都会显示此消息


我的问题是,只要
SomeOtherMethod
对该对象调用
Dispose()
,该对象就会被释放吗?我假设它会,VisualStudio继续发送消息只是因为它不知道在后续方法中该对象发生了什么,但我希望得到一些确认

无论在哪里调用
Dispose()
,它都被调用

不使用语言关键字
使用
作为一次性模式,因此在另一种方法中移动dispose是反模式的,因此这是一种不好的做法,也是潜在问题的根源

只能通过在项目生成设置中添加警告编号来删除警告

方法
Dispose()
不会销毁对象

dispose模式仅用于释放非托管资源,如windows句柄和共享内存

调用
Dispose()
后,您仍然拥有该对象,因此对该对象的引用仍保留在托管内存中

Dispose()
将在对象使用结束时调用一次,不再调用

编译器向您发送警告,因为您违反了模式使用的标准行为,即使用
using
关键字

违反标准可能是问题的根源

使用一次性对象标准是为了避免错误,它让编译器生成
try{…}finally{Dispose()}
块,以确保在正确的位置正确调用
Dispose()

因此,避免直接调用
Dispose()

除非您确定自己在做什么,否则更喜欢使用:

public void SomeMethod()
{
  using ( DisposableObject disposableObject = new DisposableObject() )
  {
    // Do some stuff with the object
    SomeOtherMethod(disposableObject);
  }
}

您的代码可能是健壮的。

它可能被释放,也可能不被释放,这取决于执行是否会到达
Dispose
调用,这是因为可以在调用
Dispose
之前抛出异常。使用
try
最后
通过
使用
关键字显式或隐式构造可以确保在任何情况下都会调用它,这就是为什么VS会向您发出警告的原因

那个物体会被处理掉吗

对不起,这是个毫无意义的问题。CLR不跟踪对象是否调用了其“dispose”方法(请参阅)

作为一般规则,创建问题的方法也应该是在其自身之后进行清理的方法,这总是更好(可读/可维护/不易出现错误等)。正如您刚刚发现的,这种模式还允许编译器进行自动检查——同样,这也是一条很好的规则,可以确保代码编译干净,没有错误或警告

在这种情况下,警告为您提供了两种方法来干净地实现这一点;就我个人而言,我更喜欢“使用”条款(这样就不必显式地调用“dispose”),比如:


}

无论哪个作用域分配了对象,都应该是该对象的所有者,也应该是该对象的处置者。简单。使用
块在其上放置一个
。使用“转移语义”,即赋予
SomeOtherMethod
所有权并让其处理对象,可能会导致混淆,最好避免。这就是IDE0067,代码分析警告。它试图告诉您,如果该方法引发异常,该对象可能不会被释放。虽然代码分析通常很难生成有关IDisposable用法的良好诊断,但这一点可能是正确的。您确实喜欢这里的using语句。只有在Dispose()调用后,如果该方法需要很长时间才能执行,则在被调用的方法中处理它才是明智的。“
Dispose()
将在对象使用结束时调用一次,不再调用。”。不同意“不再”部分<代码>处置
方法应为@Artur我同意。。。如果Dispose实现正确完成。。。但是不要认为这总是如此,因为在计算机科学中,如果说明书没有明确地引用它,就不应该相信一个实现能够做一些事情…code>IDispose
是一个没有实现的接口,可供所有编码器使用。NET Framework类确实做得很好,但是任何人都可以为自己或为
IDispose
使用关键字来实现好的或坏的
Dispose()
。。。因此模式和编译器警告的存在。我不是说规则是否总是满足,我是说你陈述了错误的语句,就像它是一个规则一样。但是你回答的主要问题是它根本没有回答这个问题。OP询问的是将
Dispose
调用移动到
SomeOtherMethod
中,而不是“实现一次性模式的正确方法”。OP对编译器警告感到恼火。无论在哪里调用dispose,它都被调用。我回答说,对一次性模式不使用language关键字
use
,因此在另一种方法中移动dispose,是一种反模式,因此它是一种不好的pr
 public void SomeMethod()
 {
     using (DisposableObject disposableObject = new DisposableObject() )
      {

           // Do some stuff with the object

           SomeOtherMethod(disposableObject);
       }