动态地创建附加属性(Create attached property dynamically)

2019-09-29 20:36发布

试图重构一个繁琐的解决方案 ,我来动态地创建附加属性,基本的高招

void SomeMethod()
{
    ...
    var dp = DependencyProperty.RegisterAttached("SomeUniqueOrGeneratedName333", typeof(object), typeof(CurrentClass));
    ...
}

这是不推荐的方式。

我使用这样的性质(大的惊喜,就像如果有人使用附加别的东西属性)作为存储一些对象数据(即绑定)有关。 它们可以使用同样的方法的拉姆达(不知道怎么叫, 我能想到的最接近的词),如日后提取:

// 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));

但它也有问题,因为它无法检索依赖属性 (也通过反射 )。 我的猜测( 随时发现 ),这是因为这些都不是类型的静态成员

这里是我的问题:这是一些呢?

我关注的是内存(即泄漏)和性能。 我可以开始使用这项技术很多,如果它被证实是好的。

五月听起来像是根据意见,但我怀疑是能单独正常进行测试。


编辑,这里是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

无论abnull 。 我只能访问dp周围路过的参考。

PS:在尝试创建具有相同的名称将引发依赖属性。 所以应该有一种方法来访问它。

Answer 1:

我明白你的意思了。 是的, DependencyPropertyDescriptor.FromName不会在你的情况帮助,因为你没有定义的目标类型的GetValue和的SetValue方法。 然而,有一种方法通过名称与位反射,让您的依赖项属性。 需要反思,因为这种有效的方法( DependencyProperty.FromName )是一些奇怪的原因内部:

// put this into window constructor
var dp = DependencyProperty.RegisterAttached("SomeName", typeof(object), typeof(MainWindow));
SetValue(dp, "test"); // even trying to set value                      
// do this only once per application
var fromNameMethod = typeof(DependencyProperty).GetMethod("FromName", BindingFlags.Static | BindingFlags.NonPublic);
var fromName = (Func<string, Type, DependencyProperty>) fromNameMethod.CreateDelegate(typeof(Func<string, Type, DependencyProperty>));
// now it's fast to call this method via delegate, almost 0 reflection costs
var a = fromName("SomeName", typeof(MainWindow));
var value = GetValue(a); // "test"

至于是不是OK使用它。 当然,这可能不是附加属性的使用目的,但我觉得这有什么问题。 依赖属性值存储在对象本身,而不是在一些静态的位置,所以他们会得到一次收集本身收集对象。 当然,你连接在注册后它们本身将不会被收集的属性,但除非你注册了太多不应该是一个问题。



文章来源: Create attached property dynamically