一、RouteValueDictionary的定义
该类是一个字典(key-value)类型,用于存储路由中的参数
public class RouteValueDictionary : IDictionary<string, object?>, IReadOnlyDictionary<string, object?>
二、RouteValueDictionary中的字段
//容量默认大小为4,area、controller、action、id
private readonly int DefaultCapacity = 4;
//存储参数键值对的数组
internal KeyValuePair<string, object?>[] _arrayStorage;
//(猜测)用于缓存从类文件中获取的元数据信息
internal PropertyStorage? _propertyStorage;
//路由参数个数计数器
private int _count;
三、RouteValueDictionary的构造函数
1、无参构造函数创建一个空字典
public RouteValueDictionary() {
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
}
2、根据数据源创建字典
public RouteValueDictionary(object? values) {
if (values is RouteValueDictionary dictionary) {
//根据传入的RouteValueDictionary创建新的字典
if (dictionary._propertyStorage != null) {
// PropertyStorage is immutable so we can just copy it.
_propertyStorage = dictionary._propertyStorage;
_count = dictionary._count;
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
return;
}
var count = dictionary._count;
if (count > 0) {
var other = dictionary._arrayStorage;
var storage = new KeyValuePair<string, object?>[count];
Array.Copy(other, 0, storage, 0, count);
_arrayStorage = storage;
_count = count;
} else {
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
}
return;
}
//根据传入的IEnumerable<KeyValuePair<string, object>>创建新的字典
if (values is IEnumerable<KeyValuePair<string, object>> keyValueEnumerable) {
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
foreach (var kvp in keyValueEnumerable) {
Add(kvp.Key, kvp.Value);
}
return;
}
//根据传入的IEnumerable<KeyValuePair<sstring, string>>创建新的字典
if (values is IEnumerable<KeyValuePair<string, string>> stringValueEnumerable) {
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
foreach (var kvp in stringValueEnumerable) {
Add(kvp.Key, kvp.Value);
}
return;
}
//创建空字典
if (values != null) {
var storage = new PropertyStorage(values);
_propertyStorage = storage;
_count = storage.Properties.Length;
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
} else {
_arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
}
}
四、RouteValueDictionary中的方法
1、静态方法
1.1 通过KeyValuePair数组创建RouteValueDictionary
public static RouteValueDictionary FromArray(KeyValuePair<string, object?>[] items) {
if (items == null) {
//如果传入的items为null,则抛出异常
throw new ArgumentNullException(nameof(items));
}
// We need to compress the array by removing non-contiguous items. We
// typically have a very small number of items to process. We don't need
// to preserve order.
//压缩数组项(不保证顺序)
var start = 0;
var end = items.Length - 1;
//压缩逻辑
while (start <= end) {
if (items[start].Key != null) {
//如果start位置不为null,则start++(head指针向后移动)
start++;
} else if (items[end].Key != null) {
//程序运行到这里说明头指针(start)指向的位置为null,并且尾指针(end)指向的位置也不为null,则
//1、将尾部元素放到头指针处
items[start] = items[end];
//2、将尾指针的位置置空
items[end] = default;
//3、头指针向后移动,尾指针向前移动
start++;
end--;
} else {
// Both null, we need to hold on 'start' since we
// still need to fill it with something.
//程序运行到这里说明头指针和尾指针所指的位置都为空,则头指针不懂,尾指针向前移动
end--;
}
}
return new RouteValueDictionary() {
//调用构造函数创建一个RouteValueDictionary实例
_arrayStorage = items!,
_count = start,
};
}