如何将List<string>转换为List<ulong>?转换赋值失败求助
解决List与List属性双向同步的问题
兄弟,我一眼就看出你问题出在哪了——你用ConvertAll实现的DocumentIds属性,每次get都会返回一个全新的List_DocumentIds里;反过来设置的时候虽然把值转成了string列表,但如果后续你直接修改DocumentIds的元素,完全不会影响到_DocumentIds,下次读取又会回到旧数据,这就是你觉得“无法正常获取或设置”的核心原因。
问题根源拆解
举个例子,当你执行:
yourInstance.DocumentIds.Add(12345);
实际上流程是:
- 调用
DocumentIds.get,通过_DocumentIds.ConvertAll(...)生成一个新的List<ulong> - 在这个新列表上执行
Add操作 - 这个新列表用完就被丢弃,原始的
_DocumentIds根本没被修改
下次再读取DocumentIds时,又会从_DocumentIds重新生成新列表,刚才添加的12345自然就不见了。
正确解决方案:自定义列表包装类
要实现双向同步,我们需要让DocumentIds的所有操作直接映射到_DocumentIds,而不是每次生成新列表。可以通过实现IList<ulong>接口来封装内部的List<string>:
// 原始的string列表 private List<string> _DocumentIds { get; set; } = new List<string>(); // 对外暴露的ulong列表 public IList<ulong> DocumentIds => new UlongStringListWrapper(_DocumentIds); // 自定义包装类,实现双向映射 private class UlongStringListWrapper : IList<ulong> { private readonly List<string> _innerStringList; public UlongStringListWrapper(List<string> innerList) { _innerStringList = innerList; } // 索引器:读取时转ulong,赋值时转string public ulong this[int index] { get { // 这里可以加异常处理,避免无效字符串导致崩溃 if (ulong.TryParse(_innerStringList[index], out var result)) return result; throw new FormatException($"无法将字符串 {_innerStringList[index]} 转换为ulong类型"); } set => _innerStringList[index] = value.ToString(); } public int Count => _innerStringList.Count; public bool IsReadOnly => _innerStringList.IsReadOnly; // 添加元素:转成string存入内部列表 public void Add(ulong item) { _innerStringList.Add(item.ToString()); } public void Clear() { _innerStringList.Clear(); } public bool Contains(ulong item) { return _innerStringList.Contains(item.ToString()); } public void CopyTo(ulong[] array, int arrayIndex) { for (int i = 0; i < Count; i++) { array[arrayIndex + i] = ulong.Parse(_innerStringList[i]); } } // 枚举器:实时转换每个元素 public IEnumerator<ulong> GetEnumerator() { return _innerStringList.Select(s => ulong.Parse(s)).GetEnumerator(); } public int IndexOf(ulong item) { return _innerStringList.IndexOf(item.ToString()); } public void Insert(int index, ulong item) { _innerStringList.Insert(index, item.ToString()); } public bool Remove(ulong item) { return _innerStringList.Remove(item.ToString()); } public void RemoveAt(int index) { _innerStringList.RemoveAt(index); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
方案优势
- 完全同步:对
DocumentIds的任何增删改操作,都会直接作用于_DocumentIds,反之修改_DocumentIds也会实时反映到DocumentIds上 - 内存高效:不需要每次生成新列表,所有操作都是直接操作原始列表
- 异常可控:可以在转换时加入
TryParse处理无效字符串,避免程序崩溃
简化场景的替代方案
如果你的场景只需要整体赋值和读取,不需要单独修改列表元素或增删,可以简化成以下代码,但要注意这种方式依然无法支持对DocumentIds的局部修改:
public List<ulong> DocumentIds { get => _DocumentIds.Select(s => ulong.Parse(s)).ToList(); set { _DocumentIds.Clear(); _DocumentIds.AddRange(value.Select(u => u.ToString())); } }
这种方式下,如果你需要修改列表,必须重新赋值整个DocumentIds,而不能直接调用Add/Remove等方法。
内容的提问来源于stack exchange,提问作者user8015938
相关产品推荐
相关产品推荐

