IDisposable - 在没有外部引用的情况下在 class 中处理什么?
IDisposable - what to Dispose in class without external references?
我有小帮手class。 classes 在内部用于确保某些类型的字符串始终具有适当的格式(邮件地址、phone 数字、id、url、键、颜色...)。
我想将它们放入 using 块中,以便能够回收变量名:
using(Id id = ids.First())
{
Container container = containers.getById(id);
...
}
foreach(Id id in ids.Skip(1))
{
Container container = containers.getById(id);
...
}
当我这样做时,Visual Studio 要求我将这些 class 标记为 Disposable
,我照做了,但我不确定如何处理方法存根。我们以"Mail Address"class为例:
public class MailAddress : IEquatable<MailAddress>, IDisposable
{
const string MAILADDRESSPATTERN = ...
protected string _address;
public MailAddress(string address)
{
if (address == null) throw new ArgumentNullException("address");
if (!Regex.IsMatch(address, MAILADDRESSPATTERN)) throw new ArgumentException("address");
this._address = address.ToLower();
}
bool IEquatable<MailAddress>.Equals(MailAddress other)
...
public override int GetHashCode()
...
...
...
public override string ToString()
...
public void Dispose()
{
throw new NotImplementedException();
}
}
Dispose
函数在这样的 class 中究竟需要做什么?我必须处理什么,垃圾收集器会自动做什么?
到目前为止,我没有在任何地方对那个 class 调用 Dispose
,它似乎工作正常。现在,class 是 Disposable
,我是否必须在整个代码中添加对 Dispose
的调用?
编译器强制您在 Id
class 中实现 IDiposable
接口,因为您将它与 using
一起使用。 using
的唯一目的是在你离开它的块后调用 IDisposable.Dispose
。所以你只能在 IDisposable
实现上使用它。
IDisposable
的目的是在不再使用对象时清理外部资源。这包括关闭文件、断开数据库连接、返回 windows 句柄等等。
因为您似乎没有要清理的东西,所以您不需要 using
声明。在那些你 有 来使用 using
的情况下(例如,你对不同类型的对象使用一种方法,其中一些对象有外部资源),你仍然必须实现 Dispose
方法来满足接口,但可以留空。
如果您的 class 是一次性的,那么您确实应该在不再需要它时丢弃它,即使 Dispose
什么也不做。如果您或其他人稍后将清理代码添加到 Dispose
,您应该依赖它被执行。
您的 Dispose
方法根本没有用处,因为您似乎没有任何非托管资源。 Dispose
仅在您想手动处理这些资源的情况下有用。
所有托管资源都由 GC 进行垃圾回收,因此您无需执行任何操作。删除 class 上的 IDisposable
似乎是合适的操作。那也需要删除无用的 using
,您可以将其换成简单的括号:
{
Id id = ids.First();
Container container = containers.getById(id);
...
}
不要这样做,你在滥用语言和 Disposable
界面/模式。
IDisposable
存在的原因非常具体,其中包括非托管资源的确定性释放,或者当您的 class 拥有一次性引用时。
这肯定不是创建局部作用域的方法,因此您可以重用变量名。如果您需要这样做,只需执行:
{
Id id = ids.First())
Container container = containers.getById(id);
...
}
不确定为什么要使用 using
关键字。当执行离开 using
的范围时,using
关键字保证调用 Dispose()
。因此 using
括号内的对象必须是 IDisposable
。如果您没有任何需要清理的资源,则无需将您的对象包装在 using
中。由于在 .net 中使用析构函数不是一个好主意,因此您将放入析构函数的逻辑通常放在 Dispose()
方法中。当与 using
关键字结合使用时,这允许控制资源管理。
我有小帮手class。 classes 在内部用于确保某些类型的字符串始终具有适当的格式(邮件地址、phone 数字、id、url、键、颜色...)。
我想将它们放入 using 块中,以便能够回收变量名:
using(Id id = ids.First())
{
Container container = containers.getById(id);
...
}
foreach(Id id in ids.Skip(1))
{
Container container = containers.getById(id);
...
}
当我这样做时,Visual Studio 要求我将这些 class 标记为 Disposable
,我照做了,但我不确定如何处理方法存根。我们以"Mail Address"class为例:
public class MailAddress : IEquatable<MailAddress>, IDisposable
{
const string MAILADDRESSPATTERN = ...
protected string _address;
public MailAddress(string address)
{
if (address == null) throw new ArgumentNullException("address");
if (!Regex.IsMatch(address, MAILADDRESSPATTERN)) throw new ArgumentException("address");
this._address = address.ToLower();
}
bool IEquatable<MailAddress>.Equals(MailAddress other)
...
public override int GetHashCode()
...
...
...
public override string ToString()
...
public void Dispose()
{
throw new NotImplementedException();
}
}
Dispose
函数在这样的 class 中究竟需要做什么?我必须处理什么,垃圾收集器会自动做什么?
到目前为止,我没有在任何地方对那个 class 调用 Dispose
,它似乎工作正常。现在,class 是 Disposable
,我是否必须在整个代码中添加对 Dispose
的调用?
编译器强制您在 Id
class 中实现 IDiposable
接口,因为您将它与 using
一起使用。 using
的唯一目的是在你离开它的块后调用 IDisposable.Dispose
。所以你只能在 IDisposable
实现上使用它。
IDisposable
的目的是在不再使用对象时清理外部资源。这包括关闭文件、断开数据库连接、返回 windows 句柄等等。
因为您似乎没有要清理的东西,所以您不需要 using
声明。在那些你 有 来使用 using
的情况下(例如,你对不同类型的对象使用一种方法,其中一些对象有外部资源),你仍然必须实现 Dispose
方法来满足接口,但可以留空。
如果您的 class 是一次性的,那么您确实应该在不再需要它时丢弃它,即使 Dispose
什么也不做。如果您或其他人稍后将清理代码添加到 Dispose
,您应该依赖它被执行。
您的 Dispose
方法根本没有用处,因为您似乎没有任何非托管资源。 Dispose
仅在您想手动处理这些资源的情况下有用。
所有托管资源都由 GC 进行垃圾回收,因此您无需执行任何操作。删除 class 上的 IDisposable
似乎是合适的操作。那也需要删除无用的 using
,您可以将其换成简单的括号:
{
Id id = ids.First();
Container container = containers.getById(id);
...
}
不要这样做,你在滥用语言和 Disposable
界面/模式。
IDisposable
存在的原因非常具体,其中包括非托管资源的确定性释放,或者当您的 class 拥有一次性引用时。
这肯定不是创建局部作用域的方法,因此您可以重用变量名。如果您需要这样做,只需执行:
{
Id id = ids.First())
Container container = containers.getById(id);
...
}
不确定为什么要使用 using
关键字。当执行离开 using
的范围时,using
关键字保证调用 Dispose()
。因此 using
括号内的对象必须是 IDisposable
。如果您没有任何需要清理的资源,则无需将您的对象包装在 using
中。由于在 .net 中使用析构函数不是一个好主意,因此您将放入析构函数的逻辑通常放在 Dispose()
方法中。当与 using
关键字结合使用时,这允许控制资源管理。