【问题标题】:adding expando properties to a typed object at runtime in c#在 C# 中在运行时向类型化对象添加扩展属性
【发布时间】:2011-03-05 14:27:08
【问题描述】:

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

public IDictionary Items { get; }

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

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

但这会阻止对象进行 GC,因为 props 集合包含一个引用。事实上,这对于我的特定用例来说还可以,因为一旦我完成了我正在使用它们的特定事物,我就可以手动清除道具,但我想知道,是否有一些巧妙的方法来绑定ExpandoObject 到 key 同时允许垃圾回收吗?

【问题讨论】:

    标签: c# garbage-collection expandoobject


    【解决方案1】:

    看看ConditionalWeakTable<TKey, TValue> Class

    ConditionalWeakTable 类使语言编译器能够在运行时将任意属性附加到托管对象。 ConditionalWeakTable 对象是一个字典,它将由键表示的托管对象绑定到由值表示的附加属性。对象的键是属性附加到的 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);       
        } 
    }
    

    【讨论】:

    • 我必须承认我不知道这存在。
    【解决方案2】:

    您可以使用WeakReference 来引用对象,以便它们仍然可以被垃圾回收。不过,您仍然需要手动清理字典,因为对象本身已被破坏。

    【讨论】:

    • 我对此进行了研究,但后来认为一定有更简单的方法!在上面的示例中,我们必须能够使用 x 找到 ExpandoObject,但实际上不能将 x 存储在 props 字典中。为了解决这个问题,我考虑使用 Dictionary>,通过执行 GetHashcode() 来存储内容,然后在列表中搜索包含对关键对象的 WeakReference 的动态。不太好,Expandos 仍然没有得到 GC。我想出了一个 Dictionary>
    • @mcintyre321:看来你很幸运,有人已经为你实现了你的字典功能。
    猜你喜欢
    • 2021-08-27
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2013-01-21
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多