C# MVC5中反射获取集合属性后无法遍历的问题求解
问题:在MVC 5 C#中通过属性名动态提取集合并遍历
我在MVC 5 C#应用里,尝试通过属性名字符串在运行时从对象中提取值。提取普通值的流程正常,但当目标属性是集合类型时,无法编写遍历该值的代码。
示例代码如下:
using System; using System.Collections.Generic; public class Program { public static void Main() { Student student = new Student { Lectures = new List<Lecture>{ new Lecture { Title="Science"}, new Lecture {Title="Math"} } }; var obj = student; string fld = "Lectures"; // 以下代码不了解Student或Lecture类型 // 仅知道"fld"是obj的一个集合类型属性 var items = obj.GetType().GetProperty(fld).GetValue(obj); foreach (var item in items) { // 处理item的代码 } } } public class Lecture { public string Title {get;set;} } public class Student { public List<Lecture> Lectures {get;set;} }
上述代码的foreach语句会出现语法错误,提示无法对object类型变量进行操作,因为object不包含GetEnumerator的公共定义。调试时能看到items确实是Lecture类型的集合,请问这个操作是否可行?
解决方案
这个操作完全可行,问题根源在于PropertyInfo.GetValue()返回的是object类型,编译器无法识别它是可枚举集合,因此需要进行类型转换,以下是几种可行的处理方式:
1. 转换为非泛型IEnumerable
将items转换为System.Collections.IEnumerable,这是所有可枚举集合的基接口,转换后即可正常遍历:
var items = obj.GetType().GetProperty(fld).GetValue(obj) as System.Collections.IEnumerable; if (items != null) { foreach (var item in items) { // 若需访问item的属性,可通过反射实现 var titleProp = item.GetType().GetProperty("Title"); if (titleProp != null) { var title = titleProp.GetValue(item); Console.WriteLine(title); } } }
2. 转换为泛型IEnumerable<object>
如果确定集合元素是引用类型,也可以转换为IEnumerable<object>,用法和非泛型版本类似:
var items = obj.GetType().GetProperty(fld).GetValue(obj) as IEnumerable<object>; if (items != null) { foreach (var item in items) { // 处理逻辑 } }
3. 使用dynamic类型
借助dynamic让运行时自动解析类型,无需显式转换,但要注意如果items实际不是可枚举类型,会抛出运行时异常:
dynamic items = obj.GetType().GetProperty(fld).GetValue(obj); foreach (var item in items) { // 可直接访问item的属性(运行时解析) Console.WriteLine(item.Title); }
注意事项
- 转换前务必做
null检查,避免空引用异常 - 若需处理集合元素的具体属性,由于编译时未知元素类型,只能通过反射或
dynamic实现
内容的提问来源于stack exchange,提问作者Gene Stempel
相关产品推荐
相关产品推荐

