Это - сценарий, созданный, чтобы помочь понять то, чего я пытаюсь достигнуть.
Я пытаюсь создать метод, который возвращает указанное свойство родового объекта
например.
public object getValue<TModel>(TModel item, string propertyName) where TModel : class{
PropertyInfo p = typeof(TModel).GetProperty(propertyName);
return p.GetValue(item, null);
}
Код выше хорошо работает при поиске свойства на TModel item
например.
string customerName = getValue<Customer>(customer, "name");
Однако, если Вы хотите узнать, каково имя группы клиента, это становится проблемой: например.
string customerGroupName = getValue<Customer>(customer, "Group.name");
Надеясь кто-то может дать мне некоторое понимание на этом сценарии выхода - спасибо.
В пространстве имен System.Web.UI есть способ сделать это:
DataBinder.Eval(source, expression);
Я предполагаю, что вам просто нужно разбить это на несколько шагов, а не пытаться сделать все за один раз, что-то вроде:
// First get the customer group Property...
CustomerGroup customerGroup = getValue<Customer>(customer, "Group");
// Then get the name of the group...
if(customerGroup != null)
{
string customerGroupName = getValue<CustomerGroup>(customerGroup, "name");
}
Так как группа является собственностью клиента, которая сама хранит имя свойства, вы также должны пойти по этому пути. Но с тех пор '.' не может быть частью имени свойства, вы можете легко использовать String.Substring для удаления первого имени свойства из строки и рекурсивного вызова вашего метода.
Вот простой метод, использующий рекурсию для решения вашей проблемы. Он позволяет вам перемещаться по графу объекта, передавая имя свойства, разделенное точками. Он работает как со свойствами, так и с полями.
static class PropertyInspector
{
public static object GetObjectProperty(object item,string property)
{
if (item == null)
return null;
int dotIdx = property.IndexOf('.');
if (dotIdx > 0)
{
object obj = GetObjectProperty(item,property.Substring(0,dotIdx));
return GetObjectProperty(obj,property.Substring(dotIdx+1));
}
PropertyInfo propInfo = null;
Type objectType = item.GetType();
while (propInfo == null && objectType != null)
{
propInfo = objectType.GetProperty(property,
BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.DeclaredOnly);
objectType = objectType.BaseType;
}
if (propInfo != null)
return propInfo.GetValue(item, null);
FieldInfo fieldInfo = item.GetType().GetField(property,
BindingFlags.Public | BindingFlags.Instance);
if (fieldInfo != null)
return fieldInfo.GetValue(item);
return null;
}
}
Пример:
class Person
{
public string Name { get; set; }
public City City { get; set; }
}
class City
{
public string Name { get; set; }
public string ZipCode { get; set; }
}
Person person = GetPerson(id);
Console.WriteLine("Person name = {0}",
PropertyInspector.GetObjectProperty(person,"Name"));
Console.WriteLine("Person city = {0}",
PropertyInspector.GetObjectProperty(person,"City.Name"));