编辑:因此,看起来唯一的方法就是使用IDisposable。我对此表示怀疑,但仍然有点不知所措。我可以为此编写一个类,该类接受@mjwills建议的Action,但是我个人仍然希望有一种方法可以不使用using块。诸如“ using(var foo = new Bar([action]);”)这样的替代语法非常有用。
在C#中,当变量超出范围时是否可以执行操作?在C ++中,当对象超出范围时,我将使用其析构函数执行某些操作,但是垃圾收集器意味着我无法(干净地)在C#中获得相同的行为。这就是我要用C ++编写的内容:
class SetOnDestruction
{
bool& m_thingToSet;
bool m_newValueForThing;
public:
SetOnDestruction(bool& thingToSet, bool newValueForThing)
: m_thingToSet(thingToSet)
, m_newValueForThing(newValueForThing)
{
}
~SetOnDestruction()
{
m_thingToSet = m_newValueForThing;
}
};
void ExampleUsage()
{
bool thingToSet = true;
{
SetOnDestruction setter(thingToSet, false);
// do some stuff here
}
// thingToSet should now be false
}
我不想使用IDisposable,因为那样的话我会将函数包装在大的using块中,实际上只是一些语法糖。
有人知道相关的东西吗?
答案 0 :(得分:-1)
如果您要销毁非托管资源,实际上我们可以使用析构函数,例如
~SetOnDestruction()
{
/* destruction things */
}
但是,当垃圾回收器销毁对象因而不确定时,就会调用此方法。
仅 的另一种方式是使用IDisposable 有关IDisposable from MSDN here
的更多信息编辑:为了纪念投反对票(和纯粹的利益),让我们看看是否应该这样做而不是是否可以这样做
假设可以通过调用类似这样的方法来强制执行本地范围
class Program
{
static void Main(string[] args)
{
LocalScopeWrapper();
}
private static void LocalScopeWrapper() // maybe I could have a better name?
{
var testObj = new TestObj();
testObj.Print();
Console.WriteLine($"Total memory used before forced collect {GC.GetTotalMemory(false)}");
testObj = null;
GC.Collect(0); // Generation 0, lets only clear the smallest Small Object Heap
Console.WriteLine($"Total memory used after forced collect {GC.GetTotalMemory(true)}");
}
private class TestObj
{
public void Print()
{
Console.WriteLine("HelloWorld");
}
}
}
在这里,我们在将对象设置为null后强制收集对象。是有道理的,但并非完全符合我们的要求,正如《大鲸》所要求的不干净。
但是,我想看看我们是否模仿C ++行为,并且有可能。
我们可以使用Pinvoke和句柄将我们的对象传递给C / C ++库,并按此great answer by @xanatos
中所示进行免费调用我很好奇我们在C#中会变得多么糟糕,这似乎是让Pinvoke删除我们鼻子下的东西来解决GC的终极方法。没什么用,但仍然很有趣。