C# 使用反射将对象强制转换为自定义类型的列表
我有以下情况: 我有一个包含列表的复合对象,我想像-Result.CustomerList.Name一样向它传递一个“路径” 结果是一个包含客户列表的对象,但也包含许多其他不同类型的列表。我想知道在这种特殊情况下客户的姓名 到目前为止我所拥有的C# 使用反射将对象强制转换为自定义类型的列表,c#,list,generics,reflection,casting,C#,List,Generics,Reflection,Casting,我有以下情况: 我有一个包含列表的复合对象,我想像-Result.CustomerList.Name一样向它传递一个“路径” 结果是一个包含客户列表的对象,但也包含许多其他不同类型的列表。我想知道在这种特殊情况下客户的姓名 到目前为止我所拥有的 private static object GetPropertyValue(this object obj, string propertyPath) { var fullPath = propertyPath.Spli
private static object GetPropertyValue(this object obj, string propertyPath)
{
var fullPath = propertyPath.Split('.');
for (int i = 0; i <= fullPath.Length - 1; i++)
{
if (obj == null) { return null; }
var part = fullPath[i];
Type type = obj.GetType();
PropertyInfo propInfo = type.GetProperty(part);
if (propInfo == null)
{
//if its a list
if (obj.GetType().GetInterfaces().Any(
k => k.IsGenericType
&& k.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
{
//get list generic argument
var argumentType = obj.GetType().GetGenericArguments()[0];
//cast obj to List of argumentType
}
else return null;
}
obj = propInfo.GetValue(obj, null);
}
return obj;
}
我无法获得语法或如何强制转换为List或List它不起作用或List
我不知道我错过了什么,也不知道怎么做
编辑::
在运行期间,可能是CustomerList、AddressList或PaymentList或任何其他类型的列表。我需要一个能够在运行时检索任何类型列表中的属性值的方法
编辑2::
结果对象的示例
public class SearchResults
{
public List<Customer> Customers { get; set; }
public List<Payment> Payments { get; set; }
public List<Address> Addresses{ get; set; }
public int totalCount { get; set; }
public bool success { get; set; }
}
public class Customer
{
public string Name { get; set; }
public long Id { get; set; }
}
public class Payment
{
public string BankName{ get; set; }
public long Id { get; set; }
}
所以像Result.Payments.BankName这样的路径应该返回给我任何东西。问题是,我无法使该方法成为访问任何列表的通用方法。我认为通过将对象强制转换为IEnumerable来枚举该对象可能更容易:
var objCollection = obj as IEnumerable;
if (objCollection == null)
{
// this is not a collection
}
else
{
// just enumerate the objCollection.
}
我设法用dynamic解决了我的问题
private static object GetPropertyValue(this object obj, string propertyPath)
{
var fullPath = propertyPath.Split('.');
for(int i = 0; i <= fullPath.Length - 1; i++)
{
if (obj == null) { return null; }
var part = fullPath[i];
Type type = obj.GetType();
PropertyInfo propInfo = type.GetProperty(part);
if (propInfo == null)
{
//if its a list
if (obj.GetType().GetInterfaces().Any(
k => k.IsGenericType
&& k.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
{
//convert to IList from object
var genericList = (IList)obj;
//returned the desired property
return genericList.Cast<dynamic>()
.First(p => p.PropertyName.ToLower().Equals(part.ToLower()))
.PropertyValue;
}
else return null;
}
obj = propInfo.GetValue(obj, null);
}
return obj;
}
此方法现在适用于我的对象中的每个列表。最明显的是,您不能在运行时强制转换,因为强制转换是编译时的事情。你总是会遇到一些不特定的对象。这可能是因为XY问题。你到底想做什么?忽略反射内容。是否有理由不传递List属性?什么传递对象和字符串路径?如果Result.CustomerList.Name中的CustomerList是一个集合,您不需要单个项的索引吗?类似于Result.CustomerList[index].Name?@Neijwiert我希望能够获取任何对象中的任何值。我有一个带有客户数据和付款数据等的对象,我希望能够获得给定类中任何属性的值-Result.CustomerData.Name;Result.Payments.BankId等等,我需要能够在运行时处理任何类型的列表,不想硬编码特定的类型