开发者

Using syntax to trigger the calling of all objects that implement Dispose method

Is it possible to use using syntax to trigger all objects that implement IDisposable interface call the corresponding Dispose() method?

For example, if the objects of ObjectOne and ObjectTwo exist in the section of interest, can we make it the way so that the Dispose() method of both objects will be called automatically. As the example shown, I knew how to do it for one Class type, but I don't know how to do this kind of trick for more than one Class type. Because the following syntax is not allowed in C#.

// This is not a valid C# statement

using( ObjectOne one = new ObjectOne();
       OjbectTwo two = new ObjectTwo() )
{
   ...  

  // hopefully, the Dispose methods of both **one** and **two** will be called.
}

A concrete example to illustrate how to trigger the auto-calling Dispose method for just one class type.

namespace ConsoleApplication1
{
    class ObjectOne : IDisposable
    {
        public string ObjectName { get; set; }

        public Obj开发者_如何转开发ectOne() : this("Empty") { }
        public ObjectOne(string objName) 
        {
            ObjectName = objName;
        }

        public void Dispose()
        {
            Console.WriteLine("ObjectOne.Dispose " + ObjectName);
        }
    }

    class ObjectTwo : IDisposable
    {
        public string ObjectTwoName { get; set; }

        public ObjectTwo() { }
        public ObjectTwo(string objName)
        {
            ObjectTwoName = objName;
        }

        public void Dispose()
        {
            Console.WriteLine("ObjectTwo.Dispose " + ObjectTwoName);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("before");

            // make sure that the Dispose method of object one1 and one2 is called
            using (ObjectOne one1 = new ObjectOne(),
                             one2 = new ObjectOne()
                   )
            {
                // section of interest
                Console.WriteLine("middle");
            }

            Console.WriteLine("after");
            Console.ReadLine();
        }
    }
}

Thank you.


You can nest using statements:

using( ObjectOne one = new ObjectOne())
   using( OjbectTwo two = new ObjectTwo() )
   {
      ...  

     // hopefully, the Dispose methods of both **one** and **two** will be called.
   }

EDIT: the only other way would be to implement a custom list of IDisposables:

public class DisposableList : List<IDisposable>, IDisposable
{
   //this is all you need if you will ONLY use it in a using statement or explicitly call Dispose;
   //there is a more developed pattern that performs disposal automatically on finalization.
   public void Dispose()
   {
      foreach(var disposable in this)
         disposable.Dispose();
   }
}

...

using(var disposables = new DisposableList{new ObjectOne(), new ObjectTwo()})
{
   //unfortunately, you must now cast the items back to their types 
   //in order to use them as anything but IDisposables.
   var objectOne = (ObjectOne)disposables[0];
   var objectTwo = (ObjectTwo)disposables[1];

   ...
}


using (ObjectOne one1 = new ObjectOne())                       
using (ObjectTwo one2 = new ObjectTwo())                      
{                 
   // !!!section of interest!!!                 
   Console.WriteLine("middle");             
}  

This will call dispose on both objects after the code block.


Take a look at the question I asked some time back

Can i have different type of objects in a C# *using* block?

using (Font font3 = new Font("Arial", 10.0f), 
           font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

The above is how you handle multiple objects of same type. As answered in the above question, you can also handle multiple objects of different types as well.


According to this:

Multiple objects can be used with a using statement, but they must be declared inside the using statement, as in the following example:

using (Font font3 = new Font("Arial", 10.0f),
            font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

Is this what you're looking for?


Edit: After testing your code, I see the problem. You can't do it with multiple types. So what about something like this:

using (ObjectOne one1 = new ObjectOne())
using (ObjectTwo one2 = new ObjectTwo()) {
    // !!!section of interest!!!
    Console.WriteLine("middle");
}

This essentially nests one using in the other.

Note: In my console this outputs:

before
middle
ObjectTwo.Dispose 
ObjectOne.Dispose Empty
after
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜