Ответ 1
Я не совсем понимаю, о чем вы спрашиваете, но я предполагаю, что вы спрашиваете, следует ли использовать свойство внутри вашего типа или ConditionalWeakTable
, к которому вы можете прикрепить такое свойство для данного конкретного экземпляра типа. Если это так, вы можете альтернативно спросить, следует ли использовать одно свойство вместо словаря, который может содержать это свойство под определенным ключом (который будет вашим конкретным экземпляром типа). Если вам не нужен такой словарь, это довольно глупо.
Понимание ConditionalWeakTable<TKey, TValue>
:
На самом деле ConditionalWeakTable
позволяет присоединять дополнительную информацию к существующим управляемым, нединамическим объектам CLR. По сути, это можно понимать просто как словарь, в котором на ключи и значения слабо ссылаются, а значение сохраняется, пока ключ жив. Более подробную информацию можно найти на MSDN.
Итак, вы должны спросить себя, каковы ваши потребности. Предполагая, что ваши типы созданы:
var classA = ClassA();
var classB = ClassB();
var other = OtherClass();
Вы хотите использовать свойство, привязанное к таким экземплярам, следующим образом:
/* set */
var other = new OtherClass();
ClassA.OtherClassTable.Add(classA, other);
/* get */
OtherClass data = null;
var result = ClassA.OtherClassTable.TryGetValue(classA, out data);
вместо этого ниже?
/* set */
classB.OtherClass = other;
/* get */
var result = classB.OtherClass;
Если нет особых потребностей, ответ кажется довольно очевидным. Есть, конечно, дальнейшие проблемы здесь:
Что такое слабая ссылка и почему вы хотите ее использовать?
Эта статья MSDN кратко объясняет тему. В основном говорится, что слабые ссылки не увеличивают время жизни объекта, позволяя собирать мусор, как только такой объект все еще может быть достигнут кодом приложения. Слабые ссылки могут быть полезны для указания на объекты, которые должны быть доступны для GC, если они не используются активно. Однако, если программа использует большое количество небольших объектов, слабые ссылки могут отрицательно повлиять на использование памяти. Темы вроде этого, и это также должно прояснить некоторые оставшиеся сомнения.
Если вы ищете пример, когда вы можете использовать ConditionalWeakTable<TKey, TValue>
стандартного Dictionary<TKey, TValue>
, представьте следующий случай. Вы хотели бы привязать словарь свойств к экземпляру во время выполнения, но в то же время не хотите препятствовать их сбору, если вы прекратили их активно использовать. К сожалению, в стандартном подходе это невозможно - GC заблокирован, потому что словарь по-прежнему содержит сильные ссылки на них, например:
var x = new object();
x.Props().Y = "hello";
static class ExpandoExtensions
{
private 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;
}
}
Конечно, вы всегда можете снять их вручную, но разве этот подход, показанный ниже, не проще?
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);
}
}
В то же время (MSDN)
Избегайте использования слабых ссылок в качестве автоматического решения проблем управления памятью. Вместо этого разработайте эффективную политику кэширования для обработки объектов вашего приложения.
Эти методы расширения, показанные выше, взяты из этого потока.