RouteValueDictionary类详解

一、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,
    };
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值