Lambda表达式使用基类属性异常及泛型扩展方法实现疑问
问题分析与解决方案
一、Find(x => x.isSelected) 不符合预期的核心原因
你遇到的第一个问题大概率是JSON序列化/反序列化时,基类的isSelected字段没有被正确赋值。虽然你说列表“填充正常”,但基类的公共字段可能因为序列化器的配置问题丢失了值:
- 比如用Newtonsoft.Json这类序列化库时,如果没有显式配置支持基类成员序列化,或者JSON文件本身就没包含
isSelected字段,那么反序列化后所有条目的isSelected都会是默认值false,自然用Find找不到符合条件的条目。 - 快速验证方式:在
Find前加调试输出,打印每个playerdata条目的isSelected值,看看是不是全为false。
解决办法
- 检查JSON文件:确认目标条目的
isSelected字段确实存在且值为true。 - 调整序列化配置:如果用Newtonsoft.Json,可以给基类添加
[JsonObject(MemberSerialization.OptOut)]特性,确保基类成员被序列化;如果涉及多态序列化,还需要配置TypeNameHandling.Auto来识别派生类。 - 遵循C#最佳实践:把基类的字段改为属性(序列化器对属性的支持更稳定,也符合封装原则):
public class BaseData { public bool IsSelected { get; set; } public int Distance { get; set; } }
二、泛型扩展方法的约束错误
你的AddToDropDown方法约束是where T : new(),这只能保证T可以无参实例化,但无法让方法访问BaseData中的isSelected等成员。要实现跨派生类的通用逻辑,必须把约束改成**where T : BaseData**,这样才能在方法里安全访问基类的公共成员。
修改后的扩展方法示例
public static int AddToDropDown<T>(this Dropdown dropdown, List<T> baseDataList, string displayText, string iconName, bool isSelected) where T : BaseData // 替换原有的new()约束 { int addedCount = 0; foreach (var item in baseDataList) { if (item.IsSelected == isSelected) { // 根据不同派生类处理显示文本,比如PlayerData取nickname string text = item switch { PlayerData pd => pd.nickname, _ => displayText }; dropdown.options.Add(new Dropdown.OptionData(text)); addedCount++; } } return addedCount; }
额外调试建议
可以在GetPlayer方法里加一段遍历代码,确认数据是否正确加载:
foreach(var pd in playerdata) { Debug.WriteLine($"Nickname: {pd.nickname}, IsSelected: {pd.isSelected}"); }
如果输出里IsSelected全是false,那肯定是序列化环节出了问题,针对性调整序列化配置即可。
内容的提问来源于stack exchange,提问作者RNB-IT
相关产品推荐
相关产品推荐

