デザインパターンの1つであるNull Objectパターンのサンプルです。JavaやC#で素直に実装したらクラス毎に用意することになりますがRealProxyを使うことによって、たった一つの実装で全てのクラスに対応します。実はこのネタ、@ITの会議室に出したヤツなのですが全然相手にされませんでした(笑)。折角なのでSingletonにしたり、WeakReferenceを使ったり、ちょっと機能アップしてます。
// ProxyによるNullオブジェクトパターン using System; using System.Collections; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Messaging; using System.Reflection; class NullProxy : RealProxy { private static Hashtable hash = new Hashtable(); private NullProxy(Type t) : base(t) {} /// <summary> /// メソッド呼び出しに割り込んで何もしないで抜ける。 /// メソッドに戻り値がある場合、参照型ならnull、値型なら初期値を返す。 /// </summary> /// <param name="msg">メッセージ通信オブジェクト</param> /// <returns>ReturnMessageオブジェクト</returns> public override IMessage Invoke(IMessage msg) { IMethodCallMessage req = msg as IMethodCallMessage; object o = null; Type t = ((MethodInfo)req.MethodBase).ReturnType; if (t != typeof(void)) o = Activator.CreateInstance(t); ReturnMessage rm = new ReturnMessage (o, null, 0, req.LogicalCallContext, req); return rm; } // 型毎にインスタンスは一つしか作らない public static object GetInstance(Type t) { lock (typeof(NullProxy)) { NullProxy result = null; // WeakReferenceを使ってGCをじゃましない WeakReference w = hash[t] as WeakReference; if (w != null) result = w.Target as NullProxy; if (result == null) { result = new NullProxy(t); hash[t] = new WeakReference(result); } // 透過プロキシを返す return result.GetTransparentProxy(); } } } // テストクラス class MyClass : MarshalByRefObject { public void Sub(int x, ref int y, out int z) { y = x * 10; z = x * 100; } public int Function() { return 100; } } interface MyInterface { void Method(); } class MyApp { static void Main(string[] args) { MyInterface mi = NullProxy.GetInstance(typeof(MyInterface)) as MyInterface; mi.Method(); Random r = new Random(); for (int i = 0; i < 100; ++i) { int y = 10; int z = 20; // 初期値をNullObjectとする MyClass my = NullProxy.GetInstance(typeof(MyClass)) as MyClass; if (r.Next() % 2 == 0) { my = new MyClass(); } // myの生成がされなくても、構わずメソッドを呼ぶ my.Sub(i, ref y, out z); Console.WriteLine("Sub: y = {0}, z = {1}", y, z); Console.WriteLine("Function: " + my.Function().ToString()); } } }