Добавление свойств расширения в типизированный объект во время выполнения в C#
Есть ли в.net способ привязать словарь свойств к экземпляру во время выполнения, т. Е. Как если бы класс базового объекта имел свойство, подобное:
public IDictionary Items { get; }
Я пришел с решением, включающим статический словарь и метод расширения
void Main()
{
var x = new object();
x.Props().y = "hello";
}
static class ExpandoExtension {
static IDictionary<object, dynamic> props = new Dictionary<object, dynamic>();
public static dynamic Props(this object key)
{
dynamic o;
if (!props.TryGetValue(key, out o)){
o = new ExpandoObject();
props[key] = o;
}
return o;
}
}
но это мешает объектам получать GC'd, так как коллекция props содержит ссылку. На самом деле, это почти нормально для моего конкретного случая использования, так как я могу очистить опоры вручную, как только я закончу с конкретной вещью, для которой я их использую, но мне интересно, есть ли какой-нибудь хитрый способ связать ExpandoObject к ключу при разрешении сбора мусора?
2 ответа
Посмотрите на класс ConditionalWeakTable
Класс ConditionalWeakTable
позволяет языковым компиляторам присоединять произвольные свойства к управляемым объектам во время выполнения. Объект ConditionalWeakTable - это словарь, который связывает управляемый объект, представленный ключом, со своим присоединенным свойством, которое представлено значением. Ключи объекта - это отдельные экземпляры класса TKey, к которому присоединено свойство, а его значения - это значения свойств, которые назначены соответствующим объектам.
По сути, это словарь, в котором на ключи и значения слабо ссылаются, а значение сохраняется, пока ключ жив.
static class ExpandoExtensions
{
private static readonly ConditionalWeakTable<object, ExpandoObject> props =
new ConditionalWeakTable<object, ExpandoObject>();
public static dynamic Props(this object key)
{
return props.GetOrCreateValue(key);
}
}
Вы можете использовать WeakReference для ссылки на объекты, чтобы они все еще могли собираться мусором. Вы все равно должны будете очистить свой словарь вручную, так как сами объекты уничтожены.