** 全体の回答を編集 ** プロパティは、オブジェクトへの弱い参照をキーとして使用するディクショナリと、プロパティとその値を格納するための文字列とオブジェクトのペアを含むディクショナリに保持されます。
オブジェクトのプロパティを設定、取得、または削除するには、オブジェクトをディクショナリの弱参照で検索します。
未使用のプロパティを破棄するには、次の 2 つの方法があります。
- 弱参照の IsAlive を確認し、false の場合は辞書のエントリを削除します
- 「拡張可能な」オブジェクトに IDisposable を実装し、破棄されるオブジェクトのプロパティを削除する拡張メソッドを呼び出します。
サンプル コードにオプションの using ブロックを含めたので、デバッグして、Dispose がRemoveProperties
拡張メソッドを呼び出す方法を確認できます。これはもちろんオプションであり、オブジェクトが GC されたときにメソッドが呼び出されます。
WeakReference、静的辞書、および IDisposable を使用したアイデアの実用的なサンプル。
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
using (PropertyLessClass plc = new PropertyLessClass())
{
plc.SetProperty("age", 25);
plc.SetProperty("name", "John");
Console.WriteLine("Age: {0}", plc.GetProperty("age"));
Console.WriteLine("Name: {0}", plc.GetProperty("name"));
}
Console.ReadLine();
}
}
}
public class PropertyLessClass : IDisposable
{
public void Dispose()
{
this.DeleteProperties();
}
}
public static class PropertyStore
{
private static Dictionary<WeakReference, Dictionary<string, object>> store
= new Dictionary<WeakReference, Dictionary<string, object>>();
public static void SetProperty(this object o, string property, object value)
{
var key = store.Keys.FirstOrDefault(wr => wr.IsAlive && wr.Target == o);
if (key == null)
{
key = new WeakReference(o);
store.Add(key, new Dictionary<string, object>());
}
store[key][property] = value;
}
public static object GetProperty(this object o, string property)
{
var key = store.Keys.FirstOrDefault(wr => wr.IsAlive && wr.Target == o);
if (key == null)
{
return null; // or throw Exception
}
if (!store[key].ContainsKey(property))
return null; // or throw Exception
return store[key][property];
}
public static void DeleteProperties(this object o)
{
var key = store.Keys.FirstOrDefault(wr => wr.IsAlive && wr.Target == o);
if (key != null)
{
store.Remove(key);
}
}
}