C#中ArrayAdapter.GetPosition用法及返回-1问题求助
搞定ArrayAdapter.GetPosition返回-1的坑
嘿,这个问题我之前也碰到过!明明列表里清清楚楚有"London",GetPosition()却返回-1,核心原因其实是Android的ArrayAdapter用equals()方法来匹配元素,而咱们肉眼看到的“相等”不一定符合equals()的判断标准,咱们一步步来排查:
1. 先排查字符串的“隐形差异”
你以为的"London"和列表里的"London"可能不是同一个东西:
- 大小写问题:比如列表里存的是
"london",你查的是"London",字符串的equals()是严格区分大小写的 - 隐藏空白:比如列表里的元素是
"London "(末尾多了空格)或者" London"(开头有空格),肉眼根本看不出来,但equals()会判定它们不相等 - 特殊字符:如果列表数据是从文件、接口读来的,可能夹杂了不可见的特殊编码字符
怎么验证?
直接遍历列表打印每个元素的细节:
foreach (var city in MyList) { Console.WriteLine($"元素内容: '{city}', 长度: {city.Length}"); }
把输出和你传入的"London"对比,看看长度和内容是不是完全一致。
2. 确认列表元素类型和查询参数匹配
如果MyList里不是存的string,而是自定义的City类(只是ToString()显示为London),那你传字符串"London"肯定匹配不上——因为equals()会先判断类型,类型不同直接返回false。
如果是自定义对象的情况:
有两种解决思路:
- 别传字符串,直接传对应的City对象实例去查
- 重写City类的
Equals()和GetHashCode(),让它能根据城市名称判断相等性,比如:
public class City { public string Name { get; set; } public override bool Equals(object obj) { // 支持和同类型对象比较 if (obj is City other) { return string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase); } // 额外支持和字符串直接比较(可选) if (obj is string cityName) { return string.Equals(Name, cityName, StringComparison.OrdinalIgnoreCase); } return false; } public override int GetHashCode() { return Name?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0; } }
3. 检查数据源是否在适配器初始化后被修改
有没有可能你初始化完ArrayAdapter之后,才把"London"加到MyList里?这种情况下适配器内部的数据集还是旧的,自然找不到新加入的元素。
解决办法:
每次修改MyList之后,一定要调用:
myadaptername.NotifyDataSetChanged();
通知适配器更新内部数据。
4. 手动遍历找索引(临时排查)
如果上面的方法都没找到问题,咱们可以绕开GetPosition(),手动遍历列表找索引,看看是不是适配器的匹配逻辑和你预期的不一样:
int targetIndex = -1; for (int i = 0; i < MyList.Count; i++) { // 用忽略大小写的比较,避免大小写坑 if (string.Equals(MyList[i], "London", StringComparison.OrdinalIgnoreCase)) { targetIndex = i; break; } }
如果这个循环能找到正确的索引,那肯定就是equals()的匹配规则出了问题,回到前面的点继续排查就行。
内容的提问来源于stack exchange,提问作者Ola
相关产品推荐
相关产品推荐

