c#反射获取对象的GetValues嵌套属性类型

本文关键字:嵌套 属性 类型 GetValues 反射 获取 取对象 | 更新日期: 2023-09-27 18:15:02

我已经搜索和测试了过去的几个小时,我似乎不能得到我想要的结果。我正在尝试从嵌套属性中获取值。

我可以得到的属性名称没有问题,与以下。

public static IList<string> GetClassPropertyNames(object myObject)
 {   
  List<string> propertyList = new List<string>();
     if (myObject != null)
     {
         var a = myObject.GetType().GetProperty("inobjects").PropertyType.GetProperties();
         foreach (var prop in a)
         {
             propertyList.Add(prop.Name.ToString());
         }             
     }
     return propertyList;               
    }

但是,如果我使用其中一个名称作为字符串来获取属性,我就无法获得正确的对象或类型GetValue(object, null)来获得我需要的值。

我正在使用下面的代码。

public static string GetNestedProperty(object myObject, string PropertyName)
    {
        string s = null;
        var a = myObject.GetType().GetProperty("inobjects").PropertyType.GetProperties();
        foreach (PropertyInfo pi in a)
        {
            if(pi.Name == PropertyName)
            {
                s = pi.GetValue(???, null).ToString();                   
            }                
        }
        return s;
    }

我想保持实际类型的泛型,因为我使用"inobjects"作为属性来获得不同类的许多属性,并希望通过单一的方式访问属性名称和值。

我只是无法在正确的级别上获得正确的对象,因此不断遇到与我的类型不相关的问题。

c#反射获取对象的GetValues嵌套属性类型

您的问题实际上归结为您需要获得立即属性的实例,以便从中提取嵌套属性的值。

具体来说,在解析嵌套属性propertyName的值之前,您需要获取直接属性"inobjects"的值(实例)。

理想情况下,您将缓存PropertyInfo实例,但为了使代码以尽可能简单的方式工作-解析值如下:

...
if (pi.Name == PropertyName)
{
    var value = 
        myObject.GetType()
                .GetProperty("inobjects")
                .GetValue(myObject, null);
    s = (string) pi.GetValue(value, null);
}

您可能有兴趣知道您不需要手动迭代每个属性,您可以使用GetProperty代替(如果属性不存在,它将返回null)。我冒昧地为你重构了你的代码:

public static string GetNestedProperty(object value, string propertyName)
{
    var type = value.GetType();
    var property = type.GetProperty("inobjects");
    value = property.GetValue(value, null);
    type = property.PropertyType;
    property = type.GetProperty(propertyName);
    if (property == null)
    {
        return null;
    }
    value = property.GetValue(value, null);
    return (string) value;
}

我可以看到一些东西:

1)(这可能不是问题,但发布它不会有什么坏处)当条件满足时,您正在使用foreach循环而没有任何形式的中断,这可能会导致一些麻烦,因为您可能有另一个满足条件的

2)这是关于您的???,这实际上是您想要从中获取值的对象。如果你知道嵌套对象在对象中的位置,只要放入一个条件来提取那个对象并保持它直到那一行。如果它是"inobjects"对象,只需打破a的设置,以便您可以获得它。像这样:

var rawNestedObject = myObject.GetType().GetProperty("inobjects");
var a = nestedObject.PropertyType.GetProperties();

那么你的???标记可以被nestedObject取代,这将是从rawNestedObject中提取的参考。

APPEND:另外,您没有在默认为公共实例属性的GetProperty调用上使用任何标志。我不知道您命名公共成员的标准是什么,所以如果您正在访问公共实例属性,请随意忽略这一段。

这将为您提供内部属性的值:

var a = obj.GetType().GetProperty("inobjects").PropertyType.GetProperties();
foreach (var item in a)
{
     if (item.Name == PropertyName)
     {
         var test = obj.GetType().GetProperty("inobjects").GetValue(obj,null);
         s = (string)test.GetType().GetProperty(PropertyName).GetValue(test, null);
     }
}

这不是最干净的方式,但这个例子可以。