依赖注入与接口实现异常:列表元素值重复问题排查与修复
问题根源分析
你遇到的问题核心在于重复使用同一个IFileModel实例,再加上_file是静态字段(这属于额外的设计失误),导致列表里所有元素都指向同一个对象——每次循环只是修改这个对象的Filepath属性,最后自然所有元素都显示最后一次赋值的"path5"。
拆解下两个关键错误:
- 静态字段
_file:静态成员属于类而非实例,就算你创建多个FileProcessor实例,也会共用同一个_file,这完全不符合你当前的业务需求。 - 复用单个实例:你在构造函数里传入一个
IFileModel后,循环中只是反复修改它的属性,再把同一个对象引用添加到列表里——列表里的元素本质上都是同一个对象,只是最后一次修改覆盖了之前的属性值。
解决方案:注入创建实例的能力(不依赖具体实现)
要在不让FileProcessor直接依赖FileModel的前提下解决问题,我们需要让FileProcessor拥有创建新IFileModel实例的能力,这里推荐两种符合依赖反转原则的方式:
方案1:注入Func<IFileModel>工厂委托(最简单快捷)
直接通过委托传递创建IFileModel的逻辑,FileProcessor只需要知道"如何获取新实例",不需要知道具体实现类:
public class FileProcessor { // 用委托存储创建新实例的逻辑,去掉静态字段 private readonly Func<IFileModel> _fileModelFactory; // 构造函数注入工厂委托 public FileProcessor(Func<IFileModel> fileModelFactory) { _fileModelFactory = fileModelFactory; } public List<IFileModel> ProcessFiles(List<string> filepaths) { List<IFileModel> output = new List<IFileModel>(); foreach(string path in filepaths) { // 每次循环都创建一个全新的IFileModel实例 var newFile = _fileModelFactory(); newFile.Filepath = path; output.Add(newFile); } return output; } }
在Main方法中传入创建FileModel的委托(仅这里依赖具体实现,FileProcessor完全解耦):
public static void Main() { List<string> filepaths = new List<string>{"path1", "path2", "path3", "path4", "path5"}; FileProcessor fileProcessor = new FileProcessor(() => new FileModel()); List<IFileModel> files = fileProcessor.ProcessFiles(filepaths); foreach(var file in files) { Console.WriteLine(file.Filepath); } }
方案2:定义IFileModelFactory接口(适合复杂场景)
如果后续需要给IFileModel添加初始化逻辑,定义工厂接口会更规范、更易扩展:
// 定义工厂接口,抽象创建逻辑 public interface IFileModelFactory { IFileModel Create(); } // 实现工厂类,仅这里依赖具体的FileModel public class FileModelFactory : IFileModelFactory { public IFileModel Create() { return new FileModel(); } } // 修改FileProcessor,注入工厂接口 public class FileProcessor { private readonly IFileModelFactory _factory; public FileProcessor(IFileModelFactory factory) { _factory = factory; } public List<IFileModel> ProcessFiles(List<string> filepaths) { List<IFileModel> output = new List<IFileModel>(); foreach(string path in filepaths) { var newFile = _factory.Create(); newFile.Filepath = path; output.Add(newFile); } return output; } }
Main方法中使用工厂类:
public static void Main() { List<string> filepaths = new List<string>{"path1", "path2", "path3", "path4", "path5"}; IFileModelFactory factory = new FileModelFactory(); FileProcessor fileProcessor = new FileProcessor(factory); List<IFileModel> files = fileProcessor.ProcessFiles(filepaths); foreach(var file in files) { Console.WriteLine(file.Filepath); } }
额外注意点
一定要去掉_file的静态修饰符——静态成员会导致多个FileProcessor实例共享同一个对象,这几乎肯定不是你想要的行为,上面的解决方案已经完全移除了这个静态字段。
内容的提问来源于stack exchange,提问作者TDMR87
相关产品推荐
相关产品推荐

