c# - 在 C# 中使用 block 的别名

标签 c# .net garbage-collection

我对以下代码有疑问:

DisposableObject holdon = null;

using (DisposableObject o = new DisposableObject())
{
    Console.WriteLine("Inside using block");
    holdon = o;
}

holdon.Method();

当我运行这段代码时,我预计会在 holdon.Method() 行出现异常,但令我惊讶的是,它很高兴地调用了 Method() 而没有任何问题。我能够确认在 o 上调用 DisposableObject.Dispose() 是在到达 using block 的末尾时。这提出了一个问题,我没有很幸运地在 MSDN 上找到答案。在 using block 之后,尽管调用了 Dispose(),但 holdon 肯定仍然指向内存中的有效对象。那么 holdon 是否仍然指向之前由 o 指向的同一个对象,还是指向 o 的副本?

最佳答案

处置对象与从内存中移除对象无关。它仅意味着对该对象调用 Dispose() 方法。所有进一步的操作都取决于您已处置的对象的 IDisposable 实现。在某些情况下,对象设置为“已处置”状态,所有进一步的操作都会引发异常 (ObjectDisposedException)。但是当您实现 IDisposable 时,您可以自由地做任何事情(或不做)。

例如这是一个完全有效的 IDisposable 实现(fiddle):

public class CrazyDisposable : IDisposable
{
    public int Counter { get; private set; }
    public void Dispose() => Counter++;
}

进一步阅读:using statement (C# Reference) .

特别是解释为什么最好将一次性对象的范围限制在 using block 中的部分:

You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use the object outside the using block, you risk causing an exception to be thrown. For this reason, it is generally better to instantiate the object in the using statement and limit its scope to the using block.

如您所见 - 它是允许的,但是当您访问已处置的对象时,您有风险

关于c# - 在 C# 中使用 block 的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44548969/

相关文章:

c# - 如何在 WPF 中绑定(bind)多个嵌套属性

c# - 在 WCF MessageEncoder 中获取 HTTP header

.net - DateTime.Parse DD/MM/YYYY 24 小时制

javascript - 关闭和垃圾收集 : most efficient way to remove consecutive nodes from a linked list

java - 如何减少 Full GC 的数量?

c# - 为什么我没有收到 "Cross-thread operation not valid"错误

c# - 关于ipv4和ipv6的ip检查

c# - .NET MailMessage 和 AlternativeViews 中的 DKIM

java - 在 Java 中,new 和 local 之间有性能差异吗?

c# - 如何确保 IsInRole 检查不使用缓存的凭据