ASP.NET Web Forms 中 SortedList 对象的用法详解
SortedList 是 .NET Framework 中一个非常有用的集合类,位于 System.Collections 命名空间。它自动按键(Key)进行排序,同时又能像数组一样通过整数索引快速访问元素,非常适合需要在页面中保存“有序的键值对数据”且不需要泛型的场景(尤其是老的 Web Forms 项目)。
SortedList 的主要特点
| 特性 | 说明 |
|---|---|
| 键值对集合 | 每个元素都是 Key/Value 对 |
| 自动排序 | 插入时自动按照 Key 的 IComparable 接口或 IComparer 进行升序排序 |
| 键必须唯一 | 重复的 Key 会抛出 ArgumentException |
| 可通过索引访问 | 既可以用 key 取值,也可以用整数索引(0 ~ Count-1)取值 |
| 非泛型 | 键和值都是 object 类型(需要装箱/拆箱,性能稍低) |
| 线程安全 | 本身不是线程安全的,多线程场景要加 lock |
基本操作示例
using System;
using System.Collections;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// 1. 创建 SortedList
SortedList sl = new SortedList();
// 2. 添加元素(会自动按 Key 排序)
sl.Add("ZhangSan", 89);
sl.Add("LiSi", 95);
sl.Add("WangWu", 76);
sl.Add("ZhaoLiu", 92);
// 如果键重复会抛异常
// sl.Add("LiSi", 100); // ArgumentException
// 3. 通过 Key 取值
int liSiScore = (int)sl["LiSi"];
// 4. 通过索引取值(索引顺序就是 Key 排序后的顺序)
string firstKey = sl.GetKey(0).ToString(); // "LiSi"
string firstValue = sl.GetValue(0).ToString(); // "95"
// 5. 遍历(两种常见方式)
// 方式一:foreach (DictionaryEntry)
foreach (DictionaryEntry item in sl)
{
string name = item.Key.ToString();
int score = (int)item.Value;
Response.Write($"{name}: {score}<br/>");
}
// 方式二:使用索引
for (int i = 0; i < sl.Count; i++)
{
string name = sl.GetKey(i).ToString();
int score = (int)sl.GetValue(i);
Response.Write($"{name}: {score}<br/>");
}
// 把 SortedList 保存到 ViewState 或 Session 中供后续使用
ViewState["StudentScores"] = sl;
}
}
在 ASP.NET Web Forms 中常见的实际应用场景
- 下拉列表(DropDownList)动态绑定并保持排序
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SortedList sl = new SortedList();
sl.Add("北京", "Beijing");
sl.Add("上海", "Shanghai");
sl.Add("广州", "Guangzhou");
sl.Add("深圳", "Shenzhen");
DropDownList1.DataSource = sl;
DropDownList1.DataTextField = "Value"; // 显示的文字
DropDownList1.DataValueField = "Key"; // 实际值
DropDownList1.DataBind();
}
}
- 页面间传递有序数据(ViewState / Session)
// Page1.aspx
SortedList cart = new SortedList();
cart.Add("苹果", 5.5m);
cart.Add("香蕉", 3.2m);
cart.Add("橙子", 4.8m);
Session["ShoppingCart"] = cart;
// Page2.aspx
SortedList cart = Session["ShoppingCart"] as SortedList;
if (cart != null)
{
GridView1.DataSource = cart;
GridView1.DataBind();
}
- 自定义比较器(按值排序或降序等)
// 实现 IComparer,按 Value(分数)降序排列
public class ScoreDescComparer : IComparer
{
public int Compare(object x, object y)
{
int a = (int)((DictionaryEntry)x).Value;
int b = (int)((DictionaryEntry)y).Value;
return b.CompareTo(a); // 降序
}
}
// 使用
SortedList sl = new SortedList(new ScoreDescComparer());
sl.Add("ZhangSan", 89);
sl.Add("LiSi", 95);
sl.Add("WangWu", 76);
// 遍历顺序:LiSi -> ZhangSan -> WangWu
注意事项(Web Forms 老项目常见坑)
| 问题 | 解决方案 |
|---|---|
| 装箱/拆箱导致性能问题 | 如果是 .NET 4.0 以上项目,强烈建议改用 SortedList<TKey,TValue> 或 SortedDictionary<TKey,TValue> |
| ViewState 过大 | SortedList 存大量数据会让 ViewState 膨胀,建议改用 Session 或 Cache |
| 多线程并发 | 加 lock:lock(sl.SyncRoot) { ... } |
| 键类型不一致 | 所有 Key 必须实现 IComparable,或提供 IComparer |
推荐的现代替代方案(如果可以升级代码)
// .NET Framework 4.0+ 推荐使用泛型版本
SortedList<string, int> sl = new SortedList<string, int>();
sl.Add("ZhangSan", 89);
// 或者需要更高性能、允许重复键时使用
SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
总结:
在老的 ASP.NET Web Forms 项目中,SortedList 是非常方便的“自动排序键值对”容器,尤其适合绑定 DropDownList、ListBox、GridView,或在 ViewState/Session 中保存少量有序数据。但在新项目或可重构的老项目中,建议优先使用泛型 SortedList<TKey,TValue> 或 SortedDictionary<TKey,TValue>。
有具体的使用场景需要代码示例,随时告诉我!