Существующие ответы в порядке; просто альтернативная перспектива: во многих сценариях желательно использовать System.ComponentModel, а не прямое отражение, поскольку это допускает сценарии свойств времени выполнения - то есть, как DataView DataView предоставляет столбцы как properties .
Производительность - по умолчанию это в значительной степени идентично, но если вы делаете это много (например, массовый импорт / экспорт данных), вы можете получить значительное повышение производительности, используя этот подход, благодаря HyperDescriptor .
Чтобы использовать System.ComponentModel, код похож, но немного отличается:
static void Main()
{
object obj = new Customer { Address = new Address { ZipCode = "abcdef" } };
object address = GetValue(obj, "Address");
object zip = GetValue(address, "ZipCode");
Console.WriteLine(zip);
}
static object GetValue(object component, string propertyName)
{
return TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}
Это дает вам ту же обработку, как если бы вы использовали привязку данных для привязки к «Address.ZipCode» (приглушая некоторые детали, такие как списки и т. Д.).
(обратите внимание, что вы можете приводить zip в виде строки и т. Д., Если знаете, что это ожидаемый тип)
Чтобы получить значение из глубокого пути (включая ту же обработку списка, которую использует привязка данных), вы должны использовать что-то вроде:
static object ResolveValue(object component, string path) {
foreach(string segment in path.Split('.')) {
if (component == null) return null;
if(component is IListSource) {
component = ((IListSource)component).GetList();
}
if (component is IList) {
component = ((IList)component)[0];
}
component = GetValue(component, segment);
}
return component;
}
Материал списка примерно отражает поведение обычного связывания данных (хотя в нем отсутствуют некоторые вещи, такие как контексты связывания, менеджеры валют и т. Д.)