src/Converters/DictionaryConverter.cs

(开头部分) 9KB

这里只显示每个文件的开头 60 行。登录后可以解锁完整代码。

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq.Expressions;
using System.Text;

namespace Rapidity.Json.Converters
{
    /// <summary>
    /// 
    /// </summary>
    internal class DictionaryConverter : TypeConverterBase, IConverterCreator
    {
        public Type KeyType { get; protected set; }

        public Type ValueType { get; protected set; }

        public DictionaryConverter(Type type, Type keyType, Type valueType) : base(type)
        {
            this.KeyType = keyType;
            this.ValueType = valueType;
        }

        protected virtual string AddKeyValueMethodName => nameof(IDictionary.Add);

        private Action<object, object, object> _setKeyValue;
        public Action<object, object, object> SetKeyValue => _setKeyValue = _setKeyValue ?? BuildSetKeyValueMethod(Type);

        protected virtual Action<object, object, object> BuildSetKeyValueMethod(Type type)
        {
            var objExp = Expression.Parameter(typeof(object), "dic");
            var keyParaExp = Expression.Parameter(typeof(object), "key");
            var valueParaExp = Expression.Parameter(typeof(object), "value");
            var dicExp = Expression.TypeAs(objExp, Type);
            var keyExp = Expression.Convert(keyParaExp, KeyType);
            var valueExp = Expression.Convert(valueParaExp, ValueType);
            //调用索引器赋值
            var property = type.GetProperty("Item", new Type[] { KeyType });
            var indexExp = Expression.MakeIndex(dicExp, property, new Expression[] { keyExp });
            var body = Expression.Assign(indexExp, valueExp);
            //var method = type.GetMethod(AddKeyValueMethodName, new Type[] { KeyType, ValueType });
            //var body = Expression.Call(dicExp, method, keyExp, valueExp);
            var expression = Expression.Lambda<Action<object, object, object>>(body, objExp, keyParaExp, valueParaExp);
            return expression.Compile();
        }

        private Func<object, IEnumerator> _getKeys;
        public Func<object, IEnumerator> GetKeys => _getKeys = _getKeys ?? BuildGetKeysMethod(Type);

        protected virtual Func<object, IEnumerator> BuildGetKeysMethod(Type type)
        {
            var objExp = Expression.Parameter(typeof(object), "dic");
            var dicExp = Expression.TypeAs(objExp, Type);

            var property = type.GetProperty(nameof(IDictionary.Keys));
            var propertyExp = Expression.Property(dicExp, property);
            Expression body = null;
            if (typeof(IEnumerator).IsAssignableFrom(property.PropertyType))
后面还有 163 行代码,解锁后查看完整代码

24 小时内免费解锁 3 个项目,之后 1 积分/个。 规则说明

AI 解读

登录后可用,每次 10 积分,解读结果公开显示在下面。

还没有人解读过这个文件。