ようこそ。睡眠不足なプログラマのチラ裏です。

クロージャーで、お手軽Singleton(遅延評価)

クロージャーでお手軽Singleton(遅延評価)です。


Singletonにしたいクラスは、Singletonであることを意味する
ISingletonインターフェイスを実装を義務付けます(ただの空インターフェイス)。
また、コンストラクタアクセシビリティはprivateやprotected等にします。それだけでおk。

        public interface ISingleton { }

        private static readonly Dictionary<Type, object> dic = new Dictionary<Type, object>();
        private static Func<T> DelayCreateInstance<T>() where T : class, ISingleton
        {
            return DelayCreateInstance<T>(new object[] { });
        }

        private static Func<T> DelayCreateInstance<T>(object[] args) where T : class, ISingleton
        {
            return (() =>
                {
                    if (dic.ContainsKey(typeof(T))) return (T)dic[typeof(T)];
                    var instance = (args.Length == 0) ?
                          (T)Activator.CreateInstance(typeof(T), true)
                        : (T)Activator.CreateInstance(typeof(T), BindingFlags.CreateInstance, null, args, null);
                    dic.Add(typeof(T), instance);
                    return instance;
                });
        }


ちなみに、ジェネリクスの型違いも別インスタンスとして扱っています。
必要に応じて、ジェネリクスの型違いも同一インスタンスとみなすようにしたりとかもアリ。
使いどころがないこともないが・・。あまり深いことは考えないでください。適当に作りました(^ω^;)