Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 已处理的闭包具有奇怪的行为_C#_Closures_Idisposable - Fatal编程技术网

C# 已处理的闭包具有奇怪的行为

C# 已处理的闭包具有奇怪的行为,c#,closures,idisposable,C#,Closures,Idisposable,我有一个这样的一次性课程: public class Person:IDisposable { public string Name{get;set;} public void Dispose() {} } public void SafeGetterDisposableTest() { Extensions.Option<string> nameGetter; using (var john = new Person { Name =

我有一个这样的一次性课程:

public class Person:IDisposable
{
    public string Name{get;set;}

    public void Dispose()
    {}
}
public void SafeGetterDisposableTest()
{
    Extensions.Option<string> nameGetter; 
    using (var john = new Person { Name = "John" })
    {
        nameGetter = john.SafeGetter(x => x.Name);
    }
    Console.WriteLine(nameGetter.Value);
}
下面是一组扩展方法,如果调用方为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);
    }
}
正如你所看到的,我得到了Option对象,并在john被释放后调用它。我原以为我会得到一个例外,但令我惊讶的是,测试正在进行。 为什么会这样?这段代码是否会导致内存泄漏

我原以为我会得到一个例外,但令我惊讶的是,这次考试太难了 工作


仅仅通过实现
IDisposable
,您不会收到
ObjectDisposedException
(或任何其他异常)。您的
Dispose
方法为空,即使在使用
语句调用对象之后,也不会更改该对象。如果在对象被释放后将其更改为在getter中抛出异常,您将得到一个异常。否则,什么也不会发生。

按照惯例,应实现
IDisposable
对象,以便在其成员被释放后进行访问时引发异常。这不是语言的行为。如果你的一次性物品实际上有一个它正在使用的未经处理的资源,然后被清理,那么你在处理它之后执行的操作可能不会正常工作,即使你没有明确地扔掉,这就是惯例。

作为旁白,你的回答暗示了什么,请正确实现
IDisposable
,请参阅。@RonBeyer,它假定该类型具有指向非托管资源的直接链接,而不是具有本身为
IDisposable
的托管引用字段。在前一个位置编写类是非常少见的,在后一个位置编写类是非常常见的。绝大多数
IDisposable
类不应该遵循这种模式。@Servy我不确定我是否遵循您的方式,即使对于没有非托管资源并且正在管理可处置资源的类,上面的实现(可能我给出了错误的链接?)仍然可以用于确保
.Dispose()
在托管类上被调用,并且只被调用一次。@RonBeyer如果您有一个组成另一个
IDisposable
对象的
IDisposable
对象在
dispose
方法中处置该对象,并且可能还跟踪该对象是否已被处置,以及您是否已完成。在这种情况下,创建终结器、使用
Dispose(bool)
方法等都是完全不合适的context@Servy我完全同意终结器,但是在一个未密封的类中使用
受保护的void Dispose(bool)
不应该被认为是不合适的,如果它是一个密封的类,我同意,但我认为在未密封的类中,它澄清了操作,而不是在
Dispose
方法中使用一次性逻辑。