我有小助手班。这些类在内部用于确保某些类型的字符串始终具有适当的格式(邮件地址,电话号码,ID,URL,键,颜色......)。
我想将它们放入使用块中,以便能够回收变量名称:
using(Id id = ids.First())
{
Container container = containers.getById(id);
...
}
foreach(Id id in ids.Skip(1))
{
Container container = containers.getById(id);
...
}
当我这样做时,Visual Studio要求我将这些类标记为Disposable
,我做了,但我不知道如何处理方法存根。我们以“邮件地址”类为例:
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
函数究竟要在这样的类中做什么?我需要处理什么,以及垃圾收集器会自动执行什么操作?
到目前为止,我没有在任何地方打电话给Dispose
,它似乎工作正常。现在,该课程为Disposable
,我是否必须在整个代码中添加对Dispose
的调用?
答案 0 :(得分:6)
不要这样做,你滥用语言和Disposable
接口/模式。
IDisposable
有非常具体的原因,其中包括非托管资源的确定性释放,或者当您的班级拥有一次性参考资料时。
绝对不是创建本地范围的方法,因此您可以重用变量名称。如果您需要这样做,只需:
{
Id id = ids.First())
Container container = containers.getById(id);
...
}
答案 1 :(得分:5)
编译器强制您在IDiposable
类中实现Id
接口,因为您将其与using
一起使用。 using
的唯一目的是在您离开后调用IDisposable.Dispose
。因此,您只能在IDisposable
实施中使用它。
IDisposable
的目的是在不再使用对象时清理外部资源。这包括关闭文件,断开与数据库的连接,返回窗口句柄等等。
由于您似乎无法进行清理,因此您无需使用using
语句。在那些 使用using
的情况下(例如,您对一些具有外部资源的不同类型的对象使用一种方法),您仍然必须实现{{1}方法来满足接口,但你可以把它留空。
如果你的课程是一次性的,你确实应该在你不再需要的时候处理它,即使Dispose
什么都不做。如果您或其他人稍后向Dispose
添加清理代码,您应该依赖它执行。
答案 2 :(得分:3)
您的Dispose
方法完全没有用处,因为您似乎没有任何非托管资源。 Dispose
仅在您要手动处理这些资源时才有用。
GC会对所有受管资源进行垃圾收集,因此您无需采取任何操作。删除课程中的IDisposable
似乎是合适的操作。这也需要删除无用的using
,你可以换成简单的括号:
{
Id id = ids.First();
Container container = containers.getById(id);
...
}
答案 3 :(得分:1)
不确定您使用using
关键字的原因。当执行离开using
的范围时,Dispose()
关键字会保留对using
的调用。因此,using
括号内的对象必须是IDisposable
。如果您没有任何需要清理的资源,则无需将对象包装在using
中。由于在.net中使用析构函数不是一个好主意,因此您在析构函数中放置的逻辑通常放在Dispose()
方法中。这允许在与using
关键字结合使用时进行受控资源管理。