我有以下两个类:
public class Address
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
public class Employee
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public Address EmployeeAddress { get; set; }
}
我有一个雇员类的实例如下:
var emp1Address = new Address();
emp1Address.AddressLine1 = "Microsoft Corporation";
emp1Address.AddressLine2 = "One Microsoft Way";
emp1Address.City = "Redmond";
emp1Address.State = "WA";
emp1Address.Zip = "98052-6399";
var emp1 = new Employee();
emp1.FirstName = "Bill";
emp1.LastName = "Gates";
emp1.EmployeeAddress = emp1Address;
我有一个方法,它根据属性名称获取属性值,如下所示:
public object GetPropertyValue(object obj ,string propertyName)
{
var objType = obj.GetType();
var prop = objType.GetProperty(propertyName);
return prop.GetValue(obj, null);
}
上述方法适用于GetPropertyValue(emp1, "FirstName")
之类的调用,但如果我尝试GetPropertyValue(emp1, "Address.AddressLine1")
,则会抛出异常,因为objType.GetProperty(propertyName);
无法找到嵌套对象属性值。有办法解决这个问题吗?
答案 0 :(得分:21)
public object GetPropertyValue(object obj, string propertyName)
{
foreach (var prop in propertyName.Split('.').Select(s => obj.GetType().GetProperty(s)))
obj = prop.GetValue(obj, null);
return obj;
}
谢谢,我来这里寻找同样问题的答案。我最终修改了原始方法以支持嵌套属性。这应该比必须进行嵌套方法调用更加健壮,这可能最终会导致超过2个嵌套级别的繁琐。
答案 1 :(得分:11)
var address = GetPropertyValue(GetPropertyValue(emp1, "Address"), "AddressLine1");
对象Employee没有名为“Address.AddressLine1”的单个属性,它有一个名为“Address”的属性,它本身有一个名为“AddressLine1”的属性。
答案 2 :(得分:8)
我使用此方法从属性中获取值(无限数量的嵌套属性),如下所示:
<强> “属性”强>
<强> “Address.Street”强>
<强> “Address.Country.Name”强>
public static object GetPropertyValue(object src, string propName)
{
if (src == null) throw new ArgumentException("Value cannot be null.", "src");
if (propName == null) throw new ArgumentException("Value cannot be null.", "propName");
if(propName.Contains("."))//complex type nested
{
var temp = propName.Split(new char[] { '.' }, 2);
return GetPropertyValue(GetPropertyValue(src, temp[0]), temp[1]);
}
else
{
var prop = src.GetType().GetProperty(propName);
return prop != null ? prop.GetValue(src, null) : null;
}
}
答案 3 :(得分:6)
这适用于无限数量的嵌套属性。
public object GetPropertyValue(object obj, string propertyName)
{
var _propertyNames = propertyName.Split('.');
for (var i = 0; i < _propertyNames.Length; i++)
{
if (obj != null)
{
var _propertyInfo = obj.GetType().GetProperty(_propertyNames[i]);
if (_propertyInfo != null)
obj = _propertyInfo.GetValue(obj);
else
obj = null;
}
}
return obj;
}
用法:
GetPropertyValue(_employee, "Firstname");
GetPropertyValue(_employee, "Address.State");
GetPropertyValue(_employee, "Address.Country.Name");
答案 4 :(得分:2)
获取Nest属性,例如Developer.Project.Name
private static System.Reflection.PropertyInfo GetProperty(object t, string PropertName)
{
if (t.GetType().GetProperties().Count(p => p.Name == PropertName.Split('.')[0]) == 0)
throw new ArgumentNullException(string.Format("Property {0}, is not exists in object {1}", PropertName, t.ToString()));
if (PropertName.Split('.').Length == 1)
return t.GetType().GetProperty(PropertName);
else
return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Split('.')[1]);
}
答案 5 :(得分:2)
还有另一种变化。简短&amp; sweet,支持任意深度属性,处理空值和无效属性:
public static object GetPropertyVal(this object obj, string name) {
if (obj == null)
return null;
var parts = name.Split(new[] { '.' }, 2);
var prop = obj.GetType().GetProperty(parts[0]);
if (prop == null)
throw new ArgumentException($"{parts[0]} is not a property of {obj.GetType().FullName}.");
var val = prop.GetValue(obj);
return (parts.Length == 1) ? val : val.GetPropertyVal(parts[1]);
}
答案 6 :(得分:1)
递归方法,一行一行...
object GetPropertyValue(object obj, string propertyName)
{
return propertyName.Contains(".") ? GetPropertyValue(obj.GetType().GetProperty(propertyName.Split(".").First()).GetValue(obj), string.Join(".", propertyName.Split(".").Skip(1))) : obj != null ? obj.GetType().GetProperty(propertyName).GetValue(obj) : null;
}
答案 7 :(得分:0)
上面的修改版本以获取多级嵌套属性
private static System.Reflection.PropertyInfo GetProperty(object t, string PropertName, out object Value)
{
Value = "";
var v = t.GetType().GetProperties();
if (t.GetType().GetProperties().Count(p => p.Name == PropertName.Split('.')[0]) == 0)
//throw new ArgumentNullException(string.Format("Property {0}, is not exists in object {1}", PropertName, t.ToString()));
return null;
if (PropertName.Split('.').Length == 1)
{
var Value1 = t.GetType().GetProperty(PropertName).GetValue(t, null);
Value = Value1;//.ToString();
return t.GetType().GetProperty(PropertName);
}
else
{
//return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Split('.')[1], out Value);
return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Substring(PropertName.IndexOf('.') + 1, PropertName.Length - PropertName.IndexOf('.') - 1), out Value);
}
}
答案 8 :(得分:0)
这适用于1级和2级对象属性,例如Firstname
和Address.AddressLine1
public object GetPropertyValue(object obj, string propertyName)
{
object targetObject = obj;
string targetPropertyName = propertyName;
if (propertyName.Contains('.'))
{
string[] split = propertyName.Split('.');
targetObject = obj.GetType().GetProperty(split[0]).GetValue(obj, null);
targetPropertyName = split[1];
}
return targetObject.GetType().GetProperty(targetPropertyName).GetValue(targetObject, null);
}
答案 9 :(得分:0)
我为此建议的类型做了一个扩展方法:
public static class TypeExtensions
{
public static PropertyInfo GetSubProperty(this Type type, string treeProperty, object givenValue)
{
var properties = treeProperty.Split('.');
var value = givenValue;
foreach (var property in properties.Take(properties.Length - 1))
{
value = value.GetType().GetProperty(property).GetValue(value);
if (value == null)
{
return null;
}
}
return value.GetType().GetProperty(properties[properties.Length - 1]);
}
public static object GetSubPropertyValue(this Type type, string treeProperty, object givenValue)
{
var properties = treeProperty.Split('.');
return properties.Aggregate(givenValue, (current, property) => current.GetType().GetProperty(property).GetValue(current));
}
}
答案 10 :(得分:0)
我在静态类中的结构类型有问题,所以我必须使用此方法GetNestedType,如果您知道属性名称,这是示例代码,如果要获取全部,可以使用GetNestedTypes
在此示例中,ExpandoObject仅用于动态添加属性和值
private void ExtractValuesFromAppconstants(string keyName)
{
Type type = typeof(YourClass);
var examination = type.GetNestedType(keyName);
if (examination != null)
{
var innerTypes = examination.GetNestedTypes();
foreach (var innerType in innerTypes)
{
Console.Writeline($"{innerType.Name}")
}
}
}