复杂反思场景

时间:2009-06-28 18:06:58

标签: c# .net reflection field

我需要一些帮助来尝试使用反射来设置这行代码:

this.extensionCache.properties[attribute]
                          = new ExtensionCacheValue((object[]) value);

this.extensionCache是​​继承自。

的基类中的内部私有字段

我可以使用以下代码访问extensionCache字段:

FieldInfo field = typeof(Principal).GetField("extensionCache",BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

但我无法弄清楚如何使用索引调用属性方法,然后将其设置为我无法查看的类的实例。

extensionCache属于以下类型:

internal class ExtensionCache
{
    private Dictionary<string, ExtensionCacheValue> cache
                   = new Dictionary<string, ExtensionCacheValue>();

    internal ExtensionCache()
    {
    }

    internal bool TryGetValue(string attr, out ExtensionCacheValue o)
    {
        return this.cache.TryGetValue(attr, out o);
    }

    // Properties
    internal Dictionary<string, ExtensionCacheValue> properties
    {
        get
        {
            return this.cache;
        }
    }
}

这是价值等级

internal ExtensionCacheValue(object[] value)
{
    this.value = value;
    this.filterOnly = false;
}

如果某个背景有助于我尝试扩展System.DirectoryServices.AccountManagement.Principal,这是所有这些方法所在的位置。

参见方法:ExtensionSet

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

首先关闭;反射到这个级别通常是代码气味;小心......

一步一步;首先,我们需要获得ExtensionCache

FieldInfo field = typeof(Principal).GetField("extensionCache",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object extCache = field.GetValue(obj);

然后我们需要properties

field = extCache.GetType().GetField("properties",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
IDictionary dict = (IDictionary) field.GetValue(extCache);

您现在可以使用dict上的索引器,使用新值:

dict[attribute] = ...

下一个问题是如何创建ExtensionCacheValue;我假设您无法访问此类型(作为内部)...

Type type = extCache.GetType().Assembly.GetType(
      "Some.Namespace.ExtensionCacheValue");
object[] args = {value}; // needed to double-wrap the array
object newVal = Activator.CreateInstance(type, args);
...
dict[attribute] = newVal;

有任何帮助吗?