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

发布于 2024-11-05 16:45:13 字数 1795 浏览 0 评论 0原文

是否可以使用using语法来触发所有实现的对象 IDisposable接口调用对应的Dispose()方法?

例如,如果感兴趣的部分中存在ObjectOne和ObjectTwo对象,我们是否可以设置这样两个对象的Dispose()方法都会被自动调用。如示例所示,我知道如何对一种类类型执行此操作,但我不知道如何对多个类类型执行这种技巧。因为 C# 中不允许使用以下语法。

// 这不是有效的 C# 语句

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

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

具体示例说明如何仅针对一种类类型触发自动调用 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();
        }
    }
}

谢谢。

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 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仙气飘飘 2024-11-12 16:45:13

您可以嵌套使用语句:

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

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

编辑:唯一的其他方法是实现 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];

   ...
}

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];

   ...
}
夜未央樱花落 2024-11-12 16:45:13
using (ObjectOne one1 = new ObjectOne())                       
using (ObjectTwo one2 = new ObjectTwo())                      
{                 
   // !!!section of interest!!!                 
   Console.WriteLine("middle");             
}  

这将在代码块之后调用两个对象的 dispose。

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.

入怼 2024-11-12 16:45:13

看看我之前问过的问题

我可以在 C# *using* 块中拥有不同类型的对象吗?

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

以上是处理相同类型的多个对象的方法。正如上面问题所回答的,您还可以处理不同类型的多个对象。

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.

为人所爱 2024-11-12 16:45:13

根据

多个对象可以与一个对象一起使用
using 语句,但它们必须是
在 using 语句中声明,
如下例所示:

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

这是您要找的吗?


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");
}

这本质上是将一个嵌套在另一个中使用。

注意:在我的控制台中输出:

before
middle
ObjectTwo.Dispose 
ObjectOne.Dispose Empty
after

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文