简体   繁体   English

使用语法触发实现Dispose方法的所有对象的调用

[英]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? 是否可以使用语法触发实现IDisposable接口的所有对象,然后调用相应的Dispose()方法?

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. 例如,如果ObjectOne和ObjectTwo的对象存在于感兴趣部分中 ,我们可以这样做吗,这样两个对象的Dispose()方法将被自动调用。 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. 如所示示例,我知道如何针对一种Class类型执行此操作,但是我不知道如何针对多种Class类型执行此操作。 Because the following syntax is not allowed in C#. 因为在C#中不允许使用以下语法。

// This is not a valid C# statement //这不是有效的C#语句

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. 一个具体示例说明如何仅针对一种类类型触发自动调用Dispose方法。

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

        public ObjectOne() : 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: 编辑:唯一的其他方法是实现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. 这将在代码块之后在两个对象上调用dispose。

Take a look at the question I asked some time back 看看我前段时间问的问题

Can i have different type of objects in a C# *using* block? 我可以在C#* using *块中使用不同类型的对象吗?

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语句可以使用多个对象,但是必须在using语句中声明它们,如以下示例所示:

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 之前\nmiddle 中间\nObjectTwo.Dispose ObjectTwo.Dispose \nObjectOne.Dispose Empty ObjectOne.Dispose空\nafter  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM