いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

IDisposableを実装しているか特定出来ない場合のusingの利用 (using, IDisposable, Dispose, Effective C#)


元ネタは、「Effective C#」という本からです。
単に私がしらなかっただけですがw


C#とかVisualBasicでプログラム書いていると
よくusingを利用します。


その際、対象となるオブジェクトがIDisposableを実装している
か否かがわからない場合があります。


そんな場合、いままでは

object obj = xxxx;
if (obj as IDisposable)
{
    // そのまま処理.
}
else
{
    IDisposable disposable = obj as IDisposable;
    using (disposable)
    {
        ...
    }
}


みたいな事をやっていたのですが
いちいち、確認しなくてもいいことを上記の本で知りました。
具体的には、

object obj = xxx;
using (obj as IDisposable)
{
    Console.WriteLine("hoge");
}


って書いて問題ないです。
対象となるオブジェクトがIDisposableを実装していない場合でも
ちゃんと"hoge"と表示されます。


以下、サンプルです。

using System;

namespace UsingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = Factory1.GetObject();
            using (data as IDisposable)
            {  
                data.Execute();
                Console.WriteLine("Factory1.GetObject");
            }

            data = Factory2.GetObject();
            using (data as IDisposable)
            {
                data.Execute();
                Console.WriteLine("Factory2.GetObject");
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
    }

    class Factory1
    {
        public static IExecutable GetObject()
        {
            return new Data1();
        }
    }

    class Factory2
    {
        public static IExecutable GetObject()
        {
            return new Data2();
        }
    }

    interface IExecutable
    {
        void Execute();
    }

    class Data1 : IDisposable, IExecutable
    {
        public void Dispose()
        {
            Console.WriteLine("Data1.Dispose");
        }

        public void Execute()
        {
            Console.WriteLine("Data1.Execute");
        }
    }

    class Data2 : IExecutable
    {
        public void Execute()
        {
            Console.WriteLine("Data2.Execute");
        }
    }
}


実行すると

Data1.Execute
Factory1.GetObject
Data1.Dispose
Data2.Execute
Factory2.GetObject

と表示されます。


試していないですが、VisualBasicの場合でも同じでしょう。
TryCastを利用して実装すればオッケイのはずです。



================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。