嗨,我是这个伟大社区的新人,我有第一个问题。希望这个人在正确的地方(我希望我的英语是正确的):
我是新手开发者,我必须改进C#应用程序,所以我找到了这个代码,我想知道这是否是正确的方法:
ObjClass obj = new ObjClass();
obj.SomeText = TextBox1.Text;
obj.SomeNumber = Convert.ToInt32(TextBox2.Text);
ObjClass的定义如下:
using System;
namespace SomeObject
{
public class ObjClass : IDisposable
{
public string SomeText { get; set; }
public int SomeNumber{ get; set; }
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
}
然后在使用对象后,完成或处理objecto的代码如下:
if(obj.SomeNumber != null)
{
//doing something else
obj.Dispose();
}
答案 0 :(得分:2)
正确的方法是不要编写Dispose
函数。最好的情况是你只是绑定GC,阻止它释放你的对象,直到它在GUI线程上调用它(减慢它)并得到它已经运行的确认。在最坏的情况下,你写得和你一样糟糕,并最终导致潜在的内存泄漏。
现在,如果您直接在对象中处理本机内存或资源(并且它很少见,您可以避免处理大部分内容或将其留给.NET),这是编写终结器的正确方法(即部分你错过了!)是:
public class Base: IDisposable
{
private bool disposed = false;
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
disposed = true;
}
}
// Use C# destructor syntax for finalization code.
~Base()
{
// Simply call Dispose(false).
Dispose (false);
}
}
如果您的代码只是阻止终结器运行,则此代码会在终结器中调用Dispose(false)
(即,当GC确定您的对象无用并尝试释放它时)或Dispose(true)
Dispose()
你自己(然后阻止GC调用终结器,这样你就不会两次处理)。
至于你如何使用它,这是正确的方法:
using(var obj = new Base())
{
// do whatever you want
// obj.Dispose() will automatically be called at the end of scope
}
在功能上等同于:
try
{
var obj = new Base();
// use the object
}
finally
{
// always called, even during exception stack unwinding
obj.Dispose();
}
同样,正确的方法不是写Dispose
。每当您被要求这样做时,框架的失败就是为您提供适当的工具来留在管理的世界中。现在这些实例越来越少。
答案 1 :(得分:1)
如果一个类是一次性的,确保它被处置的最好方法是使用using
块。
using(var foo = new ObjClass())
{
// do something
}
这将确保即使发生异常也会处置对象。
答案 2 :(得分:0)
欢迎来到IDisposable的精彩世界!我认为这是两个问题:
1)ObjClass的实现是否正确 - 是否需要实现IDisposable ?
一个类应该实现IDisposable:
的一个。因为它包含非托管资源。如果适用,请使用"标准IDispose实现" (搜索,你会发现)。 这种情况实际上非常罕见。这个类似乎不是这样的 - 它只管理了两个成员。
的湾因为该类包含实现IDisposable的托管对象,并且您希望类的用户能够控制何时释放那些管理对象所拥有的资源。请注意,它不是关于如何释放资源 - 它们最终将被GC释放 - 但是通过提供IDisposable,您可以让类用户控制何时发生这种情况。这里一个很好的例子是一个包含托管Socket对象的类。 Socket实现了IDisposable,它将关闭端口。通过类实现IDisposable并在其Dispose方法中处理套接字,您允许类用户控制套接字何时关闭。
以上都不是。或b。这里的类是这样的,因此在这里实现IDisposable似乎是错误的。
2)ObjClass实例的使用方式是否正确?
当你完成一个对象时,可以明确地调用Dispose - 这样做没有严格的错误。但是,using语句是首选的方法。重要的是(如在另一个答案中所提到的),使用块包括幕后的try / catch和最终处理对象 - 这是重要的。如果你不使用"使用"如果有异常,你应该尝试使用catch来处理对象。