我有一个像这样的一次性课程:
public class Person:IDisposable
{
public string Name{get;set;}
public void Dispose()
{}
}
这里有一组扩展方法,如果调用者为null,则返回默认值:
static class Extensions
{
public class Option<T>
{
private readonly Func<T> _resultGetter;
public bool HasValue { get; }
public Option(Func<T> resultGetter, bool hasValue)
{
_resultGetter = resultGetter;
HasValue = hasValue;
}
public T Value => _resultGetter();
}
public static Option<TResult> SafeGetter<T, TResult>(this T self, Func<T, TResult> getter, Func<TResult> defaultGetter = null) where T : class
{
defaultGetter = defaultGetter ?? (() => default(TResult));
return new Option<TResult>(self == null ? defaultGetter :()=> getter(self),self!=null);
}
}
正如您所看到的,SafeGetter
方法返回一个Option
对象,该对象具有一个带有self
参数作为闭包的getter函数。
所以为了在对象被处理后测试getter函数,我写了一个像这样的测试:
public void SafeGetterDisposableTest()
{
Extensions.Option<string> nameGetter;
using (var john = new Person { Name = "John" })
{
nameGetter = john.SafeGetter(x => x.Name);
}
Console.WriteLine(nameGetter.Value);
}
你可以看到我有了Option对象并在放置了john之后调用它。我以为我会得到一个例外但令我惊讶的是测试工作正常。 为什么会这样?这段代码是否以某种方式引入内存泄漏?
答案 0 :(得分:2)
我以为我会得到一个例外,但令我惊讶的是,测试是 工作
仅仅通过实施ObjectDisposedException
,您就不会收到IDisposable
(或任何其他例外)。您的Dispose
方法为空,即使在您的using
语句调用后,也无法更改对象。如果在对象被处理后更改它以在getter中抛出异常,则会出现异常。否则,什么都不会发生。
答案 1 :(得分:1)
约定实现了IDisposable
个对象,以便在他们的成员被处置后访问时,他们会抛出异常。这不是语言的行为。如果您的一次性物品实际上有一个正在使用的非管理资源,然后进行清理,那么即使您没有明确地投掷,大概在您处置后执行的操作也无法正常工作,因此约定。