在c#中运行时将expando属性添加到类型对象 [英] adding expando properties to a typed object at runtime in c#

查看:201
本文介绍了在c#中运行时将expando属性添加到类型对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有什么办法可以让.net在运行时将一个属性字典绑定到一个实例上,也就是说,就好像基础对象类有一个属性一样:

  public IDictionary Items {get; } 

我想出了一个涉及静态字典和扩展方法的解决方案。
$ b

  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();
道具[key] = o;
}
return o;


但这会阻止对象获取GC'd道具集合有一个参考。实际上,这对我的特殊使用情况来说确实很好,因为我可以在完成使用它们的特定事件后手动清除道具,但是我想知道,是否有一些巧妙的方法可以将ExpandoObject在允许垃圾回收的同时还可以获得密钥吗?

解决方案

查看 Conditional WeakTable< TKey,TValue> Class


b $ b

基本上它是一个字典,其中的键和值都被弱引用,并且只要键处于活动状态,值就保持有效。






  static class ExpandoExtensions 
{
private static readonly ConditionalWeakTable< object,ExpandoObject> props =
ConditionalWeakTable< object,ExpandoObject>();

public static dynamic Props(this object key)
{
return props.GetOrCreateValue(key);
}
}


Is there any way in .net to bind a dictionary of properties to an instance at runtime, i.e., as if the base object class had a property like:

public IDictionary Items { get; }

I have come up with a solution involving a static dictionary and extension method

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;       
    } 
}

but this stops the objects from getting GC'd as the the props collection holds a reference. In fact, this is just about ok for my particular use case, as I can clear the props down manually once I've finished with the particular thing I'm using them for, but I wonder, is there some cunning way to tie the ExpandoObject to the key while allowing garbage collection?

解决方案

Have a look at the ConditionalWeakTable<TKey, TValue> Class.

The ConditionalWeakTable<TKey, TValue> class enables language compilers to attach arbitrary properties to managed objects at run time. A ConditionalWeakTable<TKey, TValue> object is a dictionary that binds a managed object, which is represented by a key, to its attached property, which is represented by a value. The object's keys are the individual instances of the TKey class to which the property is attached, and its values are the property values that are assigned to the corresponding objects.

Essentially it's a dictionary where both the keys and the values are weakly referenced, and a value is kept alive as long as the key is alive.


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

这篇关于在c#中运行时将expando属性添加到类型对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆