使用反射获取第二级属性值

时间:2014-06-11 05:54:26

标签: c# c#-4.0 reflection extension-methods

我写了一个扩展方法,它获取了一个对象的属性值。这就是代码:

public static string GetValueFromProperty(this object obj, string Name)
{
    var prop = obj.GetType().GetProperty(Name);
    var propValue = prop != null ? (string)prop.GetValue(obj, null) : string.Empty;
    return propValue;
}

它适用于第一级属性。现在我遇到了问题。我想得到一个下拉列表的选定文本,我称之为这样的方法:

string s = drp.GetValueFromProperty("SelectedItem.Text");

bute它不会返回任何东西。

如何扩展从第二级属性返回值的扩展方法(或者通常形成任何级别)?

感谢

2 个答案:

答案 0 :(得分:3)

您正在尝试查找名为SelectedItem.Text的属性,但此属性在给定对象上不存在(永远不会,.是一个无法出现在属性名称中的保留字符)< / p>

您可以解析输入,将每个方法按.拆分,然后将您的通话链接在一起:

public static string GetValueFromProperty(this object obj, string Name)
{
  var methods = Name.Split('.');

  object current = obj;
  object result = null;
  foreach(var method in methods)
  {
    var prop = current.GetType().GetProperty(method);
    result = prop != null ? prop.GetValue(current, null) : null;
    current = result;
  }
  return result == null ? string.Empty : result.ToString();
}

直播示例here

修改

互惠的setter方法看起来非常相似(我在要设置的属性的类型上使它成为通用的):

public static void SetValueFromProperty<T>(this object obj, string Name, T value)
{
  var methods = Name.Split('.');

  object current = obj;
  object result = null;
  PropertyInfo prop = null;
  for(int i = 0 ; i < methods.Length - 1  ; ++i)
  {
    var method = methods[i];
    prop = current.GetType().GetProperty(method);
    result = prop != null ? prop.GetValue(current, null) : null;
    current = result;
  }

  if(methods.Length > 0)
    prop = current.GetType().GetProperty(methods[methods.Length - 1]);
  if(null != prop)
      prop.SetValue(current, value, null);
}

答案 1 :(得分:1)

快速代码(遍历树):

public static string GetValueFromProperty(this object obj, string Name)
{
    string[] names = Name.Split('.');
    object currentObj = obj;
    string value = null;
    for (int i = 0; i < names.Length; i++)
    {
        string name = names[i];
        PropertyInfo prop = currentObj.GetType().GetProperty(name);
        if (prop == null)
            break;
        object propValue = prop.GetValue(currentObj, null);
        if (propValue == null)
            break;
        if (i == names.Length - 1)
            value = (string)propValue;
        else
            currentObj = propValue;
    }
    return value ?? string.Empty;
}