使用PropertyInfo为包含自定义索引器的包装类赋值

时间:2011-07-12 14:31:49

标签: c# reflection indexer propertyinfo setvalue

我需要通过 PropertyInfo 指定一个值。

当属性的类型是我的自定义类(围绕字典的包装器,旨在包含相同文本的多个语言版本)时,我遇到了一些问题。

看起来像是:

    public class MultilingualString
    {               
        Dictionary<string, string> Versions;
        public string this[string languageCode]
        {
            get
            {
                if (Versions.Keys.Contains(languageCode))
                {
                    return Versions[languageCode];
                }
                return null;
            }
            set
            {
                if (Versions.Keys.Contains(languageCode))
                {
                    Versions[languageCode] = value;
                }
                else
                {
                    Versions.Add(languageCode, value);
                }
            }
            // [blah blah other stuff...]    
        }

因此;现在我有了这个 PropertyInfo 对象 - 以及我想用默认语言代码分配的字符串值。

certainPropertyInfo.SetValue(
   instance, // an instance of some class exposing a MultilingualString type property 
   someString,
   new[] { "eng" }); // some default language code

这引发了异常。

我猜 SetValue 的最后一个参数是一个集合索引,它不适用于自定义索引器。

有效的是,我正在努力做的事情显然是:

   instance.msProperty["eng"] = someString;

但我只给了msProperty的名字,这就是我使用反射的原因。

到目前为止,我已经考虑过实现一个隐式运算符(在MultilingualString类中),允许将字符串值转换为MultilingualString ...但我可以看到该方法的一些问题,例如。这个静态运算符几乎没有办法“知道”默认语言代码是什么。

我可以通过反思实现我的目标吗?

1 个答案:

答案 0 :(得分:3)

索引器是它自己的属性。您需要在您的某个属性中获取实例的indexer属性:

var multilingualString = certainPropertyInfo.GetValue(instance, null);
multilingualString.GetType().GetProperty("Item").SetValue(multilingualString,
                                                          someString,
                                                          new object[]{ "eng" });

Item是索引器属性的默认名称。

如果您使用的是.NET 4.0,则可以使用新的dynamic类型:

dynamic multilingualString = certainPropertyInfo.GetValue(instance, null);
multilingualString["eng"] = someString;