gpt4 book ai didi

c# - 我如何知道一个类是否是非托管资源的包装器

转载 作者:太空狗 更新时间:2023-10-29 23:06:03 24 4
gpt4 key购买 nike

我如何知道 C# 中的类是否为非托管类,以便在自定义类中使用它时我知道是否必须实现 IDisposable 接口(interface)?

如果我得到这个article在 MSDN 网络上,当我使用非托管资源时,我总是必须实现 IDisposible 接口(interface)。

所以我创建了一个小示例,您可以在下面找到:

class TestClass
{
private StreamReader reader;

public UsingTestClass()
{
reader = File.OpenText("C:\\temp\\test.txt");

string s;
while (!string.IsNullOrEmpty(s = reader.ReadLine()))
{
Console.WriteLine(s);
}

}
}

以下MSDN article例如说 File 是一个 unamanged 资源,它也在我的测试类中使用。那么我怎么能看出这个类(class)没有受到影响呢?编译器和 ReSharper 没有任何提示。

提前致谢。

最佳答案

How do I know if a class in C# is unmanaged

这会让您马上误入歧途,C# 中的所有 类都是托管的。该语言根本不支持使用非托管类。 .NET 语言都没有,除了一种:C++/CLI。这是一种相当不典型的语言,专门设计用于帮助程序员使用 native C++ 类。该语言的使用是专门的,与这个问题无关。

重要的是托管类是否是非托管资源的包装器。包装器是一种具有纯托管接口(interface)但内部使用非托管资源的类,通常通过具有 [DllImport] 属性的 pinvoke。资源几乎总是用 IntPtr 表示。非托管句柄或指针。

这样的包装器需要一个终结器来确保非托管资源总是被释放。如果这没有发生,那么您就有了泄漏,当操作系统对使用过多资源的程序感到不安时,这种错误(最终)会导致程序崩溃。

因为它有一个终结器,它也实现了 IDisposable。允许程序在 GC 开始调用终结器之前尽早释放非托管资源。使用 Dispose() 方法或 using 语句是可选的,终结器足以确保完成工作。

但有时终结器不够好,因为程序生成垃圾的速度不够快,这时您的帮助非常重要。您无法真正知道自己是否必须提供帮助,所以大多数 .NET 程序员总是这样做。在多年的编程中,一个子集从来没有也没有注意到问题。我们最终确实在 SO 收到了他们的消息 :)


您的 StreamReader 示例是进入下一步的好示例。 StreamReader 实际上并不包装非托管资源。它的所有代码都是用 C# 编写的,它没有任何 pinvoke,它的主体中没有非托管骨骼。因此没有有终结器。但是仍然有一个 Dispose() 方法。

StreamReader 被“感染”了。它也是一个包装类,但用于 Stream,而不是 IntPtr。一种纯粹托管的抽象 .NET 类型,它本身就是一个包装器。它实现了 IDisposable,现在 StreamReader 也必须实现它。因此,当您调用 StreamReader 的 Dispose() 方法时,Stream.Dispose() 方法可以运行。

这是分层在起作用,有类的层次结构。 StreamReader 包装 Stream,后者包装 FileStream,后者包装 SafeFileHandle,后者实际上包装 IntPtr。只有 SafeFileHandle 有终结器。


理解分层是每个人都放弃的地方,这需要对这些 .NET 类的结构方式有相当深入的了解。你可以到达那里,但需要数年时间。共有三个基本快捷方式:

  • 了解操作系统的工作原理。让您了解文件是一种操作系统资源,敢打赌,当您使用文件时,需要处置或关闭它。

  • 针对您使用的课​​程使用 MSDN 库文章。当您看到它有一个 Dispose() 方法时,几乎总是有充分的理由使用它。有时没有,但无论如何使用它都不会出错。

  • 惹上麻烦,犯每个程序员都需要犯的所有错误,使用 SO 或内存分析器找出你做错了什么。学习如何正确地做事永远不会错。

关于c# - 我如何知道一个类是否是非托管资源的包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35902465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com