尝试重构一个乏味的解决方案,我来到了杰出的动态创建附加属性的想法基本上是:
void SomeMethod()
{
...
var dp = DependencyProperty.RegisterAttached("SomeUniqueOrGeneratedName333", typeof(object), typeof(CurrentClass));
...
}
它不是受到推崇的 way.
我正在使用这样的属性(很惊讶,就像有人将附加属性用于其他东西一样)作为与对象数据相关的某些属性(即绑定)的存储。这些稍后在相同方法的 lambda 中检索(不知道它是如何调用的,closure我能想到的最接近的词),例如:
// create attached property an store binding to retrieve result later
var dp = DependencyProperty.RegisterAttached("LolBinding", typeof(object), typeof(CurrentClass));
BindingOperations.SetBinding(obj, dp, someBinding);
// another ap and binding, this time with event (will trigger when DataContext for obj is set)
BindingOperations.SetBinding(obj, DependencyProperty.RegisterAttached("LolAnotherBinding", typeof(object), typeof(CurrentClass), new PropertyMetadata(null, (d, e) =>
{
var value = obj.GetValue(dp); // accessing ap
if (value != null) { ... } // do something
})), Property);
这有效。我可以附加任意数量的属性:
for(int i = 0; i < 10000; i++)
DependencyProperty.RegisterAttached("SomeName" + i, typeof(object), typeof(MainWindow));
但它有问题,因为不可能检索依赖属性 (nor 通过反射)。我猜 (随意发现)这是因为那些是不是类型的静态成员.
这是我的问题:是吗?OK这样做吗?
我担心的是内存(即泄漏)和性能。如果确认没问题,我可能会开始大量使用这种技术。
可能听起来像是基于意见,但我怀疑是否能够单独正确地测试这一点。
编辑,这里是 mcve 创建和检索此类属性:
// put this into window constructor
var dp = DependencyProperty.RegisterAttached("SomeName", typeof(object), typeof(MainWindow));
SetValue(dp, "test"); // even trying to set value
// trying to access it by name
var a = DependencyPropertyDescriptor.FromName("SomeName", typeof(MainWindow), typeof(MainWindow), true);
var b = GetAttachedProperty(this, "SomeName", typeof(MainWindow)); // method from linked question
Both a
and b
are null
。我只能访问dp
通过传递引用。
P.S.:尝试创建具有相同名称的依赖属性将会抛出异常。所以应该有一种方法可以访问它。