在c#中在运行时将expando属性添加到类型化对象

mci*_*321 5 c# garbage-collection expando

在.net中是否有任何方法可以在运行时将属性字典绑定到实例,即,基本对象类具有如下属性:

public IDictionary Items { get; }
Run Code Online (Sandbox Code Playgroud)

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

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;       
    } 
}
Run Code Online (Sandbox Code Playgroud)

但这会阻止对象获取GC,因为props集合包含引用.事实上,这对于我的特定用例来说还不错,因为一旦我完成了我正在使用它们的特定事物,我可以手动清除道具,但我想知道,是否有一些狡猾的方式来绑定ExpandoObject到键,同时允许垃圾回收?

dtb*_*dtb 11

看看ConditionalWeakTable <TKey,TValue> Class.

ConditionalWeakTable <TKey,TValue>类使语言编译器能够在运行时将任意属性附加到托管对象.ConditionalWeakTable <TKey,TValue>对象是一个字典,它将一个由密钥表示的托管对象绑定到其附加属性,该属性由值表示.对象的键是附加属性的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);       
    } 
}
Run Code Online (Sandbox Code Playgroud)

  • 我必须承认我不知道这存在. (3认同)