C#中如何更新列表(List)中的对象
如何定期更新Animal列表中的对象
嘿,这个需求在日常开发里太常见了!核心思路就是基于唯一标识匹配本地数据和服务器新数据,然后做「更新现有项、添加新项、移除失效项」这三类操作,我给你一步步拆解并附上代码示例:
第一步:先明确服务器返回的数据结构
通常我们不会直接用业务实体类(比如你的Animal)来接收接口数据,建议定义一个DTO(数据传输对象)来对应服务器返回的格式:
// 服务器返回的动物数据DTO public class AnimalDto { public int CurrentPopulation { get; set; } public string Name { get; set; } // 如果有唯一ID的话,优先用ID当匹配键,比Name更可靠 // public int AnimalId { get; set; } }
第二步:实现核心的更新逻辑
我们可以在MainClass里封装一个更新方法,包含「拉取新数据、匹配更新、清理失效项」三个环节:
public class MainClass { // 建议改成私有字段,遵循C#命名规范 private List<Animal> _animalList = new List<Animal>(); // 模拟从服务器获取最新数据的方法,实际替换成你的HTTP请求逻辑(比如用HttpClient) private async Task<List<AnimalDto>> FetchLatestAnimalsFromServer() { try { // 这里写实际的接口调用代码,比如: // var response = await _httpClient.GetFromJsonAsync<List<AnimalDto>>("/api/animals"); // return response ?? new List<AnimalDto>(); // 下面是模拟数据,实际删掉 await Task.Delay(100); // 模拟网络延迟 return new List<AnimalDto> { new AnimalDto { CurrentPopulation = 105, Name = "Lion" }, // 狮子数量更新 new AnimalDto { CurrentPopulation = 22, Name = "Cat" }, // 猫数量更新 new AnimalDto { CurrentPopulation = 50, Name = "Dog" }, // 狗数量更新 new AnimalDto { CurrentPopulation = 30, Name = "Tiger" } // 新增老虎 }; } catch (Exception ex) { // 实际开发里要处理异常,比如日志记录、重试逻辑 Console.WriteLine($"拉取数据失败:{ex.Message}"); return new List<AnimalDto>(); } } // 核心更新方法 public async Task UpdateAnimalList() { // 1. 从服务器获取最新数据 var latestAnimalDtos = await FetchLatestAnimalsFromServer(); if (!latestAnimalDtos.Any()) return; // 没有新数据就直接返回 // 2. 建立本地列表的快速查找索引(用Name当唯一键,要是有ID就用ID) var localAnimalMap = _animalList.ToDictionary( animal => animal.name, animal => animal, StringComparer.OrdinalIgnoreCase // 忽略大小写,根据业务需求调整 ); // 3. 遍历新数据:更新现有项,添加新项 foreach (var dto in latestAnimalDtos) { if (localAnimalMap.TryGetValue(dto.Name, out var existingAnimal)) { // 更新现有动物的种群数量 existingAnimal.currentPopulation = dto.CurrentPopulation; } else { // 创建新Animal对象并加入列表 var newAnimal = new Animal(dto.CurrentPopulation, dto.Name); _animalList.Add(newAnimal); localAnimalMap[newAnimal.name] = newAnimal; // 更新索引,避免后续重复查找 } } // 4. 可选:移除本地有但服务器已不存在的动物(如果业务需要清理失效数据) var latestAnimalNames = latestAnimalDtos .Select(dto => dto.Name) .ToHashSet(StringComparer.OrdinalIgnoreCase); var animalsToRemove = _animalList .Where(animal => !latestAnimalNames.Contains(animal.name)) .ToList(); foreach (var animal in animalsToRemove) { _animalList.Remove(animal); } } }
第三步:实现定期更新
可以用Timer来定时触发更新操作,比如每5分钟更新一次:
public class MainClass { // ... 上面的代码 ... // 启动定期更新 public void StartPeriodicUpdate(int intervalMinutes) { var timer = new System.Timers.Timer(TimeSpan.FromMinutes(intervalMinutes).TotalMilliseconds); timer.Elapsed += async (sender, e) => { await UpdateAnimalList(); Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 动物列表已完成更新"); }; timer.AutoReset = true; // 重复触发 timer.Start(); } }
一些关键注意点
- 唯一标识的选择:如果
Name可能存在重复,一定要用唯一ID(比如AnimalId)作为匹配键,避免更新错误 - 线程安全:如果你的列表会被多个线程访问(比如UI线程和后台更新线程),要加锁(
lock(_animalList))或者用线程安全集合(比如ConcurrentBag<Animal>) - 错误处理:实际接口调用要加异常捕获,必要时加重试逻辑,避免单次更新失败导致后续任务中断
- 更新频率:根据业务场景设置合适的间隔,不要太频繁给服务器造成压力
内容的提问来源于stack exchange,提问作者lost9123193
相关产品推荐
相关产品推荐

