在List<T>中使用FindAll()方法出现类型转换错误如何解决?
错误原因
List<T>.FindAll()方法要求传入的参数是System.Predicate<T>类型的委托,你直接传入了Tower类的实例,两个类型完全不匹配,所以会触发类型转换失败的报错。- 额外注意:你的代码里还有两处隐性问题:一是
Tower类定义的属性是小写name/hight,实例化对象时用了大写Name/Hight,大小写不统一会触发编译错误;二是高度的正确英文拼写是Height,建议修正避免后续维护歧义。
正确实现方案
方案1:使用Lambda表达式(最常用写法)
直接在FindAll参数里写筛选规则的Lambda表达式,输入参数是列表中的每个Tower实例,返回布尔值表示是否符合筛选条件:
namespace Example { class Tower { // 统一修正为C#规范的PascalCase命名 public string Name { get; set; } public int Height { get; set; } } class Program { static void Main (string[] args) { List<Tower> towers = new List<Tower>(); towers.Add(new Tower() { Name = "tower1", Height = 25 }); towers.Add(new Tower() { Name = "tower2", Height = 50 }); towers.Add(new Tower() { Name = "tower3", Height = 25 }); // 传入Lambda作为谓词筛选高度为25的塔 List<Tower> short_towers = towers.FindAll(t => t.Height == 25); } } }
方案2:单独声明谓词方法
如果筛选规则比较复杂,或者需要复用,可以单独定义符合Predicate<T>签名的静态方法,直接传入方法名即可:
namespace Example { class Tower { public string Name { get; set; } public int Height { get; set; } } class Program { // 定义筛选规则的谓词方法 static bool FilterShortTower(Tower t) { return t.Height == 25; } static void Main (string[] args) { List<Tower> towers = new List<Tower>(); towers.Add(new Tower() { Name = "tower1", Height = 25 }); towers.Add(new Tower() { Name = "tower2", Height = 50 }); towers.Add(new Tower() { Name = "tower3", Height = 25 }); // 直接传入方法名作为参数 List<Tower> short_towers = towers.FindAll(FilterShortTower); } } }
补充说明:
Predicate<T>是返回布尔值的泛型委托,作用是自定义匹配规则:遍历列表时每个元素都会传入该委托,返回true的元素会被加入FindAll的返回结果集。
内容的提问来源于stack exchange,提问作者backofenp0mmes
相关产品推荐
相关产品推荐

