是否可以编写C#以便在对象超出范围时对其进行垃圾回收?

del*_*ber 6 c# garbage-collection

例如,在下面的代码中,将创建一个'image'对象,然后在将来某个未知点收集垃圾

void MyFunction() {

    Bitmap image = RetrieveImage();
    DoSomething(image);
}
Run Code Online (Sandbox Code Playgroud)

关于什么

void MyFunction() {

    DoSomething(RetrieveImage());

}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,一旦它移出范围,即在MyFunction结束后收集的对象垃圾.如果没有,有什么地方可以执行此操作?

Jon*_*eet 19

实际上,你真的不希望它被垃圾收集 - 经常提示垃圾收集器会降低性能.

什么,你想要的是及时处置的非托管资源的-而这也正是IDisposable进来,与沿using语句:

void MyFunction()
{
    using (Bitmap image = RetrieveImage())
    {
        DoSomething(image);
    }
}
Run Code Online (Sandbox Code Playgroud)

无论是否抛出异常,这将image.Dispose()在它离开using声明时调用DoSomething.

你必须虽然使用额外的变量-除非你改变DoSomething采取Func<Bitmap>相反,所以不是:

void DoSomething(Bitmap image)
{
    // Code here
}
...
DoSomething(RetrieveImage());
Run Code Online (Sandbox Code Playgroud)

你有:

void DoSomething(Func<Bitmap> imageProvider)
{
    using (Bitmap image = imageProvider())
    {
        // Code here
    }
}
...
DoSomething(() => RetrieveImage());
Run Code Online (Sandbox Code Playgroud)

请注意,这并没有提供传递位图的机会,不会被丢弃 - 如果您想稍后再次使用它,这可能是个问题.至少,这是一个至少知道的好方法.

编辑:正如mbeckish在他的评论中指出的那样,仅仅处理内部的位图并没有太大的好处RetrieveImage.以下是该模式的变体:

public void ApplyToEachLineInFile(string file, Action<string> action)
{
    using (TextReader reader = File.OpenText(file))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            action(line);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的"获取和处理"逻辑是封装的,没有调用者担心它 - 但调用者在传递逻辑的复杂性方面仍然可以非常灵活.