书签列表属性无法赋值及自动排序实现的技术求助
解决书签列表属性排序与赋值问题
首先得明确:你当前的属性实现会触发无限递归,这就是它不生效的核心原因。当你在get访问器里写return Bookmarks.OrderBy(...)时,每次获取Bookmarks属性,都会再次调用它自己的get访问器,陷入循环,要么栈溢出,要么根本拿不到正确的值。
下面给你几个实用的解决方案,按需选择:
方案一:用私有字段存储原始数据(最通用的写法)
通过私有后台字段存储未排序的列表,get访问器返回排序后的副本,set访问器给字段赋值:
// 私有字段,用来存储原始的书签列表 private List<UIBookmark> _bookmarks; public List<UIBookmark> Bookmarks { get { // 为空时返回空列表,避免空引用;不为空则按名称排序后返回新列表 return _bookmarks?.OrderBy(b => b.Name).ToList() ?? new List<UIBookmark>(); } set { // 直接赋值给私有字段,也可以在这里提前排序(看你需求) _bookmarks = value; // 如果希望赋值时就把列表排好序,改成下面这样: // _bookmarks = value?.OrderBy(b => b.Name).ToList() ?? new List<UIBookmark>(); } }
这种写法的好处是:每次获取Bookmarks都会拿到最新排序的结果,同时避免了递归问题。如果你的列表数据会频繁变动,这个方案很合适。
方案二:在赋值时直接排序(最简单的写法)
如果你的书签列表赋值后不会频繁修改,完全可以把排序逻辑放到赋值的地方,保持属性的简单自动实现:
// 保持原来的自动属性写法 public List<UIBookmark> Bookmarks { get; set; } // 赋值时直接加上排序 model.Bookmarks = GetBookmarks() .Select(b => new UIBookmark(b, DbHelper)) .OrderBy(b => b.Name) // 在这里完成A-Z排序 .ToList();
这种写法最简洁,没有额外的属性逻辑,性能也更好——因为只在赋值时排序一次,而不是每次访问属性都排序。
方案三:只读属性+内部加载(适合数据不允许外部修改的场景)
如果Bookmarks不需要外部直接赋值,只需要从数据源加载并保持排序,可以改成只读属性,用内部方法加载数据:
private List<UIBookmark> _bookmarks; // 用IReadOnlyList防止外部修改列表内容 public IReadOnlyList<UIBookmark> Bookmarks => _bookmarks?.OrderBy(b => b.Name).ToList() ?? new List<UIBookmark>(); // 内部加载数据的方法 public void LoadBookmarks() { _bookmarks = GetBookmarks().Select(b => new UIBookmark(b, DbHelper)).ToList(); }
这种写法可以避免外部代码随意修改书签列表,适合数据由内部统一管理的场景。
额外提醒
- 尽量避免在属性的
get访问器里做排序这类耗时操作,如果列表数据量大,每次访问都排序会有性能损耗。 - 如果你的列表会频繁更新,建议在更新数据后主动调用排序,而不是依赖
get访问器每次排序。
内容的提问来源于stack exchange,提问作者Teije
相关产品推荐
相关产品推荐

