Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.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中引用已处理的对象_C#_Dispose_Idisposable - Fatal编程技术网

C# 在C中引用已处理的对象

C# 在C中引用已处理的对象,c#,dispose,idisposable,C#,Dispose,Idisposable,如果这是一个愚蠢的问题,我很抱歉,但是在您明确地处理了一个对象之后,您不应该再次引用该对象。。。对吧? 这通常是个坏主意,对吗 SomeObject o = new SomeObject(); o.DoStuff(); o.Dispose(); o.DoMoreStuff(); 还有,是否有过这样的情况需要这样做?在需要之前,您永远不会处理对象。处置一个物体意味着你不再需要它了。当你不再需要这个东西的时候,如果它是一次性的,你会把它处理掉。因此,在对象被释放后,永远不会有访问对象的机会。

如果这是一个愚蠢的问题,我很抱歉,但是在您明确地处理了一个对象之后,您不应该再次引用该对象。。。对吧?

这通常是个坏主意,对吗

SomeObject o = new SomeObject();

o.DoStuff();

o.Dispose();

o.DoMoreStuff();

还有,是否有过这样的情况需要这样做?

在需要之前,您永远不会处理对象。处置一个物体意味着你不再需要它了。当你不再需要这个东西的时候,如果它是一次性的,你会把它处理掉。因此,在对象被释放后,永远不会有访问对象的机会。

除非您需要,否则您永远不会释放对象。处置一个物体意味着你不再需要它了。当你不再需要这个东西的时候,如果它是一次性的,你会把它处理掉。因此,在对象被释放后,永远没有访问对象的意义。

对象的释放告诉它释放所有非托管资源,因此你必须问自己的问题是,没有这些资源,对象能做任何有意义的事情吗。这将取决于对象的具体情况

大多数IDisposable对象的设计都是这样的:如果在处理实例后尝试调用它们的方法,它们将抛出异常,或者更糟的是,只会执行意外行为

即使在被处理之后,其他对象仍然可能有有意义的事情要做。例如,DataTable实现IDisposable,但有意义的数据往往存储在托管资源中,而不是非托管资源中。在其当前的实现中,它的Dispose方法可能会发生变化,但它不会做任何事情,所以在它被释放后使用它就可以了。话虽如此,当您仍计划使用它时,没有令人信服的理由来处置它

同样可以想象的是,一个对象在被处理后重新创建它所需要的任何资源,这将是一个坏主意,但仍然是可能的


综上所述,专门设计一个即使在处理后仍打算使用的对象被认为是一种不好的做法,一次性对象的意图也是在处理完毕之前不处理它。这里的要点是,即使您不应该这样做,而且它经常会在您面前爆炸,这将是因为选择实现类是为了符合约定,而不是因为它是一项技术要求。

处理对象会告诉它释放其所有非托管资源,因此,你必须问自己的问题是,没有这些资源,对象能做任何有意义的事情吗。这将取决于对象的具体情况

大多数IDisposable对象的设计都是这样的:如果在处理实例后尝试调用它们的方法,它们将抛出异常,或者更糟的是,只会执行意外行为

即使在被处理之后,其他对象仍然可能有有意义的事情要做。例如,DataTable实现IDisposable,但有意义的数据往往存储在托管资源中,而不是非托管资源中。在其当前的实现中,它的Dispose方法可能会发生变化,但它不会做任何事情,所以在它被释放后使用它就可以了。话虽如此,当您仍计划使用它时,没有令人信服的理由来处置它

同样可以想象的是,一个对象在被处理后重新创建它所需要的任何资源,这将是一个坏主意,但仍然是可能的


综上所述,专门设计一个即使在处理后仍打算使用的对象被认为是一种不好的做法,一次性对象的意图也是在处理完毕之前不处理它。这里的要点是,即使你不应该这样做,而且它经常会在你脸上爆炸,这将是因为选择实现类是为了符合约定,而不是因为它是一项技术要求。

尽管在理论上,绝对没有什么可以阻止您创建一个允许您处置然后继续使用该对象的类,除了检查物品是否已被处理外,我想不出还有哪种情况需要这样做,例如

通常使用的模式只是丢弃已处置对象,并在必要时重新创建它们,事实上,在许多情况下,尝试访问已处置对象将导致抛出ObjectDisposedException。如果您正在创建一个实现的对象,那么遵循此约定将是一个好主意

要帮助跟踪哪些对象已被释放和未被释放,并确保您的对象已被释放,即使在引发异常的情况下,也可以使用以下语句:

using (SomeObject o = new SomeObject())
{
    o.DoStuff();
}

虽然在理论上,没有任何东西可以阻止您创建一个类,该类允许您处理并继续使用该对象,但我想不出有哪一种情况下 除了检查物品是否已被处理外,还需要他的检查,例如

通常使用的模式只是丢弃已处置对象,并在必要时重新创建它们,事实上,在许多情况下,尝试访问已处置对象将导致抛出ObjectDisposedException。如果您正在创建一个实现的对象,那么遵循此约定将是一个好主意

要帮助跟踪哪些对象已被释放和未被释放,并确保您的对象已被释放,即使在引发异常的情况下,也可以使用以下语句:

using (SomeObject o = new SomeObject())
{
    o.DoStuff();
}

我喜欢在实现IDisposable时使用此模式

private bool m_disposed;

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

public void Dispose(bool disposing)
{
    if (!m_disposed)
    {
        if (disposing)
            // Cleanup and close resources

        m_disposed = true;
    }
}
然后在我的类中的所有其他方法中,我将这样做

public void DoMoreStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

  // Your code here
}

public void DoStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

    // Your code here
 }

我喜欢在实现IDisposable时使用此模式

private bool m_disposed;

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

public void Dispose(bool disposing)
{
    if (!m_disposed)
    {
        if (disposing)
            // Cleanup and close resources

        m_disposed = true;
    }
}
然后在我的类中的所有其他方法中,我将这样做

public void DoMoreStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

  // Your code here
}

public void DoStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

    // Your code here
 }


小澄清。这通常不是一个坏主意。这总是个坏主意。如果你还需要使用这个东西,它就不应该被处理掉。你通常会把食物放进垃圾桶,然后再把它拉出来吃吗?@Gabe-有时候我忘了买食品了。@ChaosPandion,哈哈,真臭!真的@不是真的。有一些场景很少见,而且通常隐藏在公众视野中,这是有意义的。因此,老年退休金计划“一般”比“总是”更准确。小澄清。这通常不是一个坏主意。这总是个坏主意。如果你还需要使用这个东西,它就不应该被处理掉。你通常会把食物放进垃圾桶,然后再把它拉出来吃吗?@Gabe-有时候我忘了买食品了。@ChaosPandion,哈哈,真臭!真的@不是真的。有一些场景很少见,而且通常隐藏在公众视野中,这是有意义的。所以OPs“通常”比“总是”更准确。一种允许在表单被释放后读取表单内容的模式比一种要求在表单被释放前读取表单中的所有信息的模式要好,而这种模式反过来要求ShowDialog将表单保持在关闭但未被释放的状态。@supercatWindows窗体只是Win32 API的包装器-一旦窗体被释放,窗口句柄就被清除,因此基于Win32 API的任何信息(如窗体维度)都不再可用,因为这些函数需要有效的窗口句柄。通常,我希望当窗体关闭时,表单的代码将知道表单或其控件的哪些属性将继续受到关注,因此可以确保以某种方式持久化这些属性。如果希望干净地关闭套接字连接,然后处理在关闭之前交换的所有信息,则存在一些类似的问题。可以使用关闭、读取、处置、,但我不喜欢在关闭可以执行Dispose的所有基本操作的情况下要求先关闭再处理。允许在处理表单后读取表单内容的模式比要求在处理表单之前读取表单中的所有信息的模式要好,而这反过来又要求ShowDialog使窗体处于关闭但未释放状态。@supercat Windows窗体只是Win32 API的包装器-一旦窗体被释放,窗口句柄就被清除,因此基于Win32 API的任何信息(如窗体维度)将不再可用,因为这些函数需要有效的窗口一般来说,我希望当表单关闭时,表单的代码会知道表单或其控件的哪些属性将继续受到关注,从而可以确保以某种方式持久化这些属性。如果希望干净地关闭套接字连接,然后处理在关闭之前交换的所有信息,则存在一些类似的问题。可以使用序列Close、Read、Dispose,但我不喜欢在Close可以执行Dispose的所有基本操作的情况下要求在Dispose之前关闭。在许多情况下,可能希望在对象的所有资源都可以释放之后从对象检索信息。将Dispose延迟到检索到所有必要的信息,这可能发生在不同的应用程序层,而不是发现对象的资源可以释放的应用程序层。参见ShowDialog,这通常不如简单地让内层获取资源,使用它收集信息,然后释放资源,使对象保持收集的信息对调用方可用的状态。那么这是一个与设计相关的问题,与已处置的对象无关。基本的经验法则是,你将在处理完对象后处理它,包括在你的案例中检索对象信息
void问题是将一个IDisposable对象以某种方式绑定到一个非一次性对象,该对象将维护在IDisposable对象的生命周期之后应该保持的信息。例如,无模式FindAndReplaceDialog对话框可以保存对FindAndReplaceParams对象的引用,该对象将被对话框更新。但是,如果对象不是由框本身创建的,那么如果将同一对象分配给两个对话框,则语义可能不明确;如果对象是由长方体本身创建的,那么要求在Dispose之前获取对该对象的引用似乎会令人厌烦。考虑一下,也许一个合理的方法是将应该可用的信息封装到一个对象中,该对象将在IDisposable创建时创建,引用将永远作为一个不可变的属性提供?这样就可以清楚地知道哪些信息保证保持可用,哪些信息不可用。在许多情况下,用户可能希望在对象的所有资源都可以释放之后从对象检索信息。将Dispose延迟到检索到所有必要的信息,这可能发生在不同的应用程序层,而不是发现对象的资源可以释放的应用程序层。参见ShowDialog,这通常不如简单地让内层获取资源,使用它收集信息,然后释放资源,使对象保持收集的信息对调用方可用的状态。那么这是一个与设计相关的问题,与已处置的对象无关。基本的经验法则是,您将在完成对象的所有操作(包括您的案例中的对象信息检索)后对其进行处理。当然,避免此问题的一种方法是将IDisposable对象以某种方式绑定到非一次性对象,该对象将保留应保留的信息超过IDisposable对象的生存期。例如,无模式FindAndReplaceDialog对话框可以保存对FindAndReplaceParams对象的引用,该对象将被对话框更新。但是,如果对象不是由框本身创建的,那么如果将同一对象分配给两个对话框,则语义可能不明确;如果对象是由长方体本身创建的,那么要求在Dispose之前获取对该对象的引用似乎会令人厌烦。考虑一下,也许一个合理的方法是将应该可用的信息封装到一个对象中,该对象将在IDisposable创建时创建,引用将永远作为一个不可变的属性提供?这样,就可以清楚地知道哪些信息是保证可以获得的,哪些信息不是。