You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确初始化List<KeyValuePair<string,HashSet<string>>>?添加元素时值异常变更排查

问题根源:复用了同一个引用类型实例

你遇到的问题核心在于引用类型的特性:HashSet<string>是引用类型,而你在整个循环中一直复用同一个txtFiles实例。

当你把txtFiles添加到KeyValuePair并加入列表时,并没有复制一份新的HashSet,只是把这个集合的内存地址(引用)存进了列表的元素里。所以列表里所有的KeyValuePair<string, HashSet<string>>的值,其实都指向同一个HashSet对象——每次循环里的txtFiles.Clear()和后续添加操作,都是在修改这个唯一的集合,自然会导致之前列表元素里的值跟着变化。


解决方案:每次循环创建新的HashSet实例

把HashSet<string>的初始化移到foreach循环内部,这样每次处理一个文件时,都会创建一个全新的HashSet,避免引用复用:

List<KeyValuePair<string, HashSet<string>>> logTxtFilesList = new List<KeyValuePair<string, HashSet<string>>>();

DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
recentFiles = dirInfo.EnumerateFiles();
string pattern = @"^.*\|END_OF_PARAM\|([A-Za-z0-9_-]+\.txt)$"; // 补充:原代码的正则需要加@转义,否则会编译报错
foreach (FileInfo file in recentFiles)
{
    // 每次循环都新建一个HashSet,不再复用旧实例
    HashSet<string> txtFiles = new HashSet<string>();
    using (FileStream fs = File.Open(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (BufferedStream bs = new BufferedStream(fs))
    using (StreamReader sr = new StreamReader(bs))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
        {
            Match match = Regex.Match(line, pattern);
            if (match.Success)
            {
                string FileName = match.Groups[1].ToString();
                if (txtFiles.Add(FileName))
                {
                    // 数据库插入操作
                }
            }
        }
    }
    logTxtFilesList.Add(new KeyValuePair<string, HashSet<string>>(file.Name, txtFiles));
}

补充说明:KeyValuePair<TKey, TValue>本身是值类型,但它的TValue如果是引用类型(比如HashSet),存储的还是引用。所以只要多个KeyValuePair的TValue指向同一个引用类型实例,修改这个实例就会影响所有对应的KeyValuePair。通过每次循环新建HashSet,就能保证每个列表元素都持有独立的集合实例,不会互相干扰。

内容的提问来源于stack exchange,提问作者m_beta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:37:44