C#-从子类获取属性值
我在运行时使用C#中的反射从类对象访问属性值 我将属性名作为参数:fieldName传递给此方法。 现在,我需要在运行时从上述类的子对象访问属性值。C#-从子类获取属性值,c#,reflection,C#,Reflection,我在运行时使用C#中的反射从类对象访问属性值 我将属性名作为参数:fieldName传递给此方法。 现在,我需要在运行时从上述类的子对象访问属性值。 有人能告诉我如何访问子对象属性值吗 使用反射获取子对象,然后使用反射以相同的方式获取值。由于您希望能够在任意嵌套的子对象上查找对象,因此需要一个可以递归调用的函数。这一点很复杂,因为您的子对象可能会引用它们的父对象,因此您需要跟踪在搜索中看到的对象 public void Main(){ var containerObject = new
有人能告诉我如何访问子对象属性值吗 使用反射获取子对象,然后使用反射以相同的方式获取值。由于您希望能够在任意嵌套的子对象上查找对象,因此需要一个可以递归调用的函数。这一点很复杂,因为您的子对象可能会引用它们的父对象,因此您需要跟踪在搜索中看到的对象
public void Main(){
var containerObject = new ContainerObject();
object propertyValue;
object nestedPropertyValue;
if(GetValue(containerObject, "FirstPropertyName", out propertyValue){
bool success = GetValue(propertyValue, "NestedPropertyName", out nestedPropertyValue);
}
}
public bool GetValue(object currentObject, string propertyName, out object propertyValue)
{
// Get type of current record
var currentObjectType = currentObject.GetType();
PropertyInfo propertyInfo = currentObjectType.GetProperty(propertyName);
propertyValue = propertyInfo != null
? propertyInfo.GetValue(currentObject,null)
: null;
return propertyValue == null;
}
static bool GetValue(object currentObject, string propName, out object value)
{
// call helper function that keeps track of which objects we've seen before
return GetValue(currentObject, propName, out value, new HashSet<object>());
}
static bool GetValue(object currentObject, string propName, out object value,
HashSet<object> searchedObjects)
{
PropertyInfo propInfo = currentObject.GetType().GetProperty(propName);
if (propInfo != null)
{
value = propInfo.GetValue(currentObject, null);
return true;
}
// search child properties
foreach (PropertyInfo propInfo2 in currentObject.GetType().GetProperties())
{ // ignore indexed properties
if (propInfo2.GetIndexParameters().Length == 0)
{
object newObject = propInfo2.GetValue(currentObject, null);
if (newObject != null && searchedObjects.Add(newObject) &&
GetValue(newObject, propName, out value, searchedObjects))
return true;
}
}
// property not found here
value = null;
return false;
}
与其像
GetValue(“foo”,out val)
那样调用它,不如像GetValue(“foo.bar”,out val)
这样调用它。您有什么问题吗?这里还有其他问题吗?编辑了我的问题,需要一种访问子对象属性值的方法。您的意思是使用GetNestedTypes()?谢谢smartcaveman,但我事先不知道主对象的哪个特定属性将是嵌套属性的父属性。在这种情况下,您的代码片段无法解决我的问题。您可以使用GetProperties而不是GetProperty(name)来获取所有属性。如果您进一步指定目标,我可以为您提供更多帮助。在我的情况下,提供每个属性的路径名是不可能的,因为有数百个属性。想要一种简单有效的方法,让我的代码可以深入到子对象并获取只提供父对象和属性名称作为输入的属性值。所以你说你有一个对象树,其中所有对象中的每个属性都有一个唯一的名称,你想找到一个只给出名称的任意嵌套属性吗?(如果你有foo.bar.baz.qux,你只需要传入“qux”,让函数知道它在'foo.bar.baz'中。)因纽坦:这会使事情变得非常复杂。看我修改过的函数。谢谢盖布。请添加以前的函数,将每个属性的路径名作为参数传递。。。可能需要。谢谢Gabe,我所做的唯一更改是删除currentObject=property.GetValue(currentObject,null.ToString())中的“ToString()”;
static bool GetValue(object currentObject, string propName, out object value)
{
// call helper function that keeps track of which objects we've seen before
return GetValue(currentObject, propName, out value, new HashSet<object>());
}
static bool GetValue(object currentObject, string propName, out object value,
HashSet<object> searchedObjects)
{
PropertyInfo propInfo = currentObject.GetType().GetProperty(propName);
if (propInfo != null)
{
value = propInfo.GetValue(currentObject, null);
return true;
}
// search child properties
foreach (PropertyInfo propInfo2 in currentObject.GetType().GetProperties())
{ // ignore indexed properties
if (propInfo2.GetIndexParameters().Length == 0)
{
object newObject = propInfo2.GetValue(currentObject, null);
if (newObject != null && searchedObjects.Add(newObject) &&
GetValue(newObject, propName, out value, searchedObjects))
return true;
}
}
// property not found here
value = null;
return false;
}
public bool GetValue(string pathName, out object fieldValue)
{
object currentObject = _currentObject;
string[] fieldNames = pathName.Split(".");
foreach (string fieldName in fieldNames)
{
// Get type of current record
Type curentRecordType = currentObject.GetType();
PropertyInfo property = curentRecordType.GetProperty(fieldName);
if (property != null)
{
currentObject = property.GetValue(currentObject, null).ToString();
}
else
{
fieldValue = null;
return false;
}
}
fieldValue = currentObject;
return true;
}