如何在C#中从对象数组中仅移除字符串类型元素?
问题排查与解决方案
嘿,我帮你分析下代码里的问题,以及怎么修复它:
原代码的核心问题
你的代码里主要有两个关键问题:
- 遍历集合时直接修改集合:用
foreach遍历ArrayList的时候调用Remove,会破坏迭代器的状态,要么抛出InvalidOperationException异常,要么因为集合元素索引偏移,导致部分字符串元素被跳过(比如连续两个字符串的话,第二个会没被检查到)。 - 非泛型集合的类型不安全问题:
ArrayList是旧的非泛型集合,类型转换时容易出问题,不如泛型集合或Linq操作来得安全高效。
修复方案
方案1:修复原有ArrayList的遍历逻辑(反向遍历)
如果想保留ArrayList的使用,可以改成从后往前反向遍历删除,这样就不会因为元素删除导致索引错乱:
using System; using System.Collections; using System.Linq; public class Program { public static int[] FilterArray(object[] arr) { ArrayList myAL = new ArrayList(arr); // 反向遍历,避免删除元素后索引偏移导致漏删 for (int i = myAL.Count - 1; i >= 0; i--) { if (myAL[i] is string) { myAL.RemoveAt(i); } } return myAL.Cast<int>().ToArray(); } }
方案2:使用泛型集合+批量删除
换成泛型List<object>,先收集所有要删除的字符串元素,再批量删除,避免遍历中修改集合:
using System; using System.Collections.Generic; using System.Linq; public class Program { public static int[] FilterArray(object[] arr) { List<object> list = new List<object>(arr); // 先收集所有需要删除的字符串元素 var stringsToRemove = list.Where(item => item is string).ToList(); foreach (var str in stringsToRemove) { list.Remove(str); } return list.Cast<int>().ToArray(); } }
方案3:用Linq一行解决(最简洁优雅)
其实C#的Linq提供了现成的方法OfType<T>,可以直接过滤出指定类型的元素,自动排除其他类型,代码非常简洁:
using System; using System.Linq; public class Program { public static int[] FilterArray(object[] arr) { // OfType<int>会自动过滤掉所有非int类型的元素,直接返回int序列 return arr.OfType<int>().ToArray(); } }
这个方法既避免了手动遍历的各种坑,又保证了类型安全,是最推荐的解决方案~
内容的提问来源于stack exchange,提问作者Artamiel
相关产品推荐
相关产品推荐

