Should you do it: probably not, except for very exceptional scenarios where you are in complete control of the types.
Can you do it: this depends entirely on the implementation - and you certainly wouldn't want to apply that at random to arbitrary types. If, however, the type is (as part of cleanup) returned to some pool and re-initialized and re-used, then yes it will work. But: you risk problems if the // do something
code leaked the reference somewhere.
can I prevent this kind of exception?
yes: don't access an object after you've disposed it
saying that "Object synchronization method was called from an unsynchronized block of code."
I wonder - are you perhaps using await
here? or an iterator block? or something like that? If the enter and exit code runs on different threads, it will fail.
If your intent here is to minimize allocations of LockerHolder
, there is a better approach: use a struct
:
using System;
struct Foo : IDisposable
{
public Foo(string msg)
{
Console.WriteLine("Init: " + msg);
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
static class Program
{
static void Main()
{
Console.WriteLine("Before");
using (new Foo("Hi"))
{
Console.WriteLine("Do stuff");
}
Console.WriteLine("After");
}
}
The Main
method here compiles the Dispose
using constrained
-call, which means it doesn't box.
Note that for this to work, the LockHolderCreater.Create
method must return the struct itself - it cannot return just IDisposable
.