C# 支持复用字典的复杂元素

C# 支持复用字典的复杂元素

演示项目 CloudResourceConfigs.zip





namespace System.Data.CloudResources.Common
{
    using System.Collections.Generic;

    /// <summary>
    /// 支持根据元素相同字典(描述哪一些元素是相同的字典),查找元素的信息。
    /// </summary>
    class TryGetValueFunc<TValue>
    {
        public TryGetValueFunc(Dictionary<string, string> sameItemDic, Dictionary<string, TValue> itemDic, IEqualityComparer<string> keyComparer)
        {
            this.SameItemDic = sameItemDic;
            this.ItemDic = itemDic;
            this.DefaultKeyComparer = keyComparer;
        }

        /// <summary>
        /// 元素相同字典(描述哪一些元素是相同的字典)。
        /// </summary>
        protected Dictionary<string, string> SameItemDic { get; set; }

        /// <summary>
        /// 元素的信息的字典。
        /// </summary>
        protected Dictionary<string, TValue> ItemDic { get; set; }

        private IEqualityComparer<string> DefaultKeyComparer { get; set; }

        public bool TryGetValue(string key, out TValue value)
        {
            return TryGetValue(key, null, out value);
        }

        public bool TryGetValue(string key, List<string> tryGetKeyList, out TValue value)
        {
            var isFindInDic = false;
            value = default(TValue);
            var safeItemDic = ItemDic;
            if (safeItemDic != null && key != null)
            {
                isFindInDic = safeItemDic.TryGetValue(key, out value);
                if (tryGetKeyList == null) tryGetKeyList = new List<string>(10);
                tryGetKeyList.Add(key);

                if (!isFindInDic || object.Equals(value, default(TValue)))
                {
                    var safeSameItemDic = SameItemDic;
                    string newKey;
                    if (safeSameItemDic != null && safeSameItemDic.TryGetValue(key, out newKey) &&
                        newKey != null && !Contains(tryGetKeyList, newKey, DefaultKeyComparer) &&
                        TryGetValue(newKey, tryGetKeyList, out value))
                    {
                        isFindInDic = true;
                    }
                }
            }

            return isFindInDic;
        }

        private static bool Contains(IList<string> list, string value, IEqualityComparer<string> comparer)
        {
            bool isContains = false;
            foreach (var item in list)
            {
                if (comparer.Equals(item, value))
                {
                    isContains = true;
                    break;
                }
            }
            return isContains;
        }
    }
}


namespace System.Data.CloudResources.Common
{
    using System.Collections.Generic;

    /// <summary>
    /// 支持根据元素相同字典(描述哪一些元素是相同的字典),查找元素的信息。
    /// 支持先查 ProductId(PID) ,再查语言(LanguageId),最后查默认值(DefaultId)。
    /// </summary>
    class TryGetProductIdInfoFunc<TValue> : TryGetValueFunc<TValue>
    {
        public TryGetProductIdInfoFunc(Dictionary<string, string> sameItemDic,
            Dictionary<string, TValue> itemDic, IEqualityComparer<string> keyComparer)
            : base(sameItemDic, itemDic, keyComparer)
        {
        }

        public TValue GetProductIdInfo(string productId, string languageId)
        {
            TValue value;
            TryGetProductIdInfo(productId, languageId, KeyInfo.DefaultId, out value);
            return value;
        }

        public TValue GetProductIdInfo(string productId, string languageId, string defaultId)
        {
            TValue value;
            TryGetProductIdInfo(productId, languageId, defaultId, out value);
            return value;
        }

        public bool TryGetProductIdInfo(out TValue value)
        {
            return TryGetProductIdInfo(KeyInfo.CurrentProductId, KeyInfo.CurrentLanguageId, KeyInfo.DefaultId, out value);
        }

        public bool TryGetProductIdInfo(string productId, string languageId, out TValue value)
        {
            return TryGetProductIdInfo(productId, languageId, KeyInfo.DefaultId, out value);
        }

        public bool TryGetProductIdInfo(string productId, string languageId, string defaultId, out TValue value)
        {
            var tryGetKeyList = new List<string>(20);
            var isFindInDic = TryGetValue(productId, tryGetKeyList, out value);
            if ((!isFindInDic || object.Equals(value, default(TValue))) &&
                TryGetValue(languageId, tryGetKeyList, out value))
            {
                isFindInDic = true;
            }
            if ((!isFindInDic || object.Equals(value, default(TValue))) &&
                !KeyInfo.DefaultKeyComparer.Equals(defaultId, languageId) &&
                TryGetValue(defaultId, tryGetKeyList, out value))
            {
                isFindInDic = true;
            }
            return isFindInDic;
        }
    }
}

namespace System.Data.CloudResources.Common
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// 按照分组信息字典,对元素集合进行分组。
    /// </summary>
    /// <typeparam name="TItem"></typeparam>
    class GetItemsByGroupFunc<TItem>
    {
        public GetItemsByGroupFunc(TItem[] items, Dictionary<string, int[]> itemsGroupDic)
        {
            this.Items = items;
            this.ItemsGroupDic = itemsGroupDic;
        }

        /// <summary>
        /// 元素的分组信息字典。
        /// 可能为 null 。为 null 表示所有元素的分组的下标都为 0 。
        /// </summary>
        private Dictionary<string, int[]> ItemsGroupDic { get; set; }

        /// <summary>
        /// 元素的信息的列表。
        /// </summary>
        private TItem[] Items { get; set; }

        public TItem[] GetItemsByGroup(int groupIndex, string languageId)
        {
            return GetItemsByGroup(groupIndex, languageId, KeyInfo.DefaultLanguageId);
        }

        public TItem[] GetItemsByGroup(int groupIndex, string languageId, string defaultLanguageId)
        {
            TItem[] safeItems = Items;
            if (safeItems == null) safeItems = new TItem[0];
            int[] findGroup = GetItemsGroup(languageId, defaultLanguageId);

            TItem[] findItemsByGroup;
            if (findGroup == null)
            {
                if (groupIndex == 0)
                {
                    findItemsByGroup = safeItems;
                }
                else
                {
                    findItemsByGroup = new TItem[0];
                }
            }
            else
            {
                findItemsByGroup = GetItemsByGroupCore(groupIndex, safeItems, findGroup);
            }
            return findItemsByGroup;
        }

        private TItem[] GetItemsByGroupCore(int groupIndex, TItem[] safeItems, int[] findGroup)
        {
            TItem[] findItemsByGroup;
            if (groupIndex >= 0 && groupIndex < findGroup.Length)
            {
                var beginIndexForGroup = GetBeginIndexForGroup(groupIndex, findGroup);
                var lengthForGroup = findGroup[groupIndex];
                lengthForGroup = Math.Min(lengthForGroup, safeItems.Length - beginIndexForGroup);
                lengthForGroup = Math.Max(lengthForGroup, 0);
                findItemsByGroup = new TItem[lengthForGroup];
                if (lengthForGroup > 0)
                {
                    Array.Copy(safeItems, beginIndexForGroup, findItemsByGroup, 0, lengthForGroup);
                }
            }
            else
            {
                findItemsByGroup = new TItem[0];
            }
            return findItemsByGroup;
        }

        private int[] GetItemsGroup(string languageId, string defaultLanguageId)
        {
            int[] safeGroup = null;
            var safeGroupDic = ItemsGroupDic;
            if (languageId != null && safeGroupDic != null &&
                !safeGroupDic.TryGetValue(languageId, out safeGroup))
            {
                safeGroupDic.TryGetValue(defaultLanguageId, out safeGroup);
            }
            return safeGroup;
        }

        private int GetBeginIndexForGroup(int groupIndex, int[] findGroup)
        {
            var beginIndexForGroup = 0;
            for (int index = 0; index < groupIndex; ++index)
            {
                beginIndexForGroup += findGroup[index];
            }
            return beginIndexForGroup;
        }
    }
}


namespace System.Data.CloudResources.Common
{
    using System;
    using System.Collections.Generic;

    public static class KeyInfo
    {
        private static string currentLanguageId = "chinese";

        public static int DefaultCapacity
        {
            get { return 40; }
        }

        public static StringComparer DefaultKeyComparer
        {
            get { return StringComparer.OrdinalIgnoreCase; }
        }

        public static string DefaultId { get { return "default"; } }

        public static string DefaultLanguageId
        {
            get { return "english"; }
        }

        public static string CurrentLanguageId
        {
            get { return currentLanguageId; }
            set
            {
                if (!DefaultKeyComparer.Equals(currentLanguageId, value))
                {
                    currentLanguageId = value;
                    OnCurrentLanguageIdChanged();
                }
            }
        }

        public static string CurrentProductId
        {
            get { return "englishProductId"; }
        }

        public static string UserDataProductName
        {
            get { return "UserDataProductName"; }
        }

        public static event EventHandler CurrentLanguageIdChanged;

        internal static IDictionary<string, string> GetAllProductIdLanguageId()
        {
            var dic = new KeyDictionary<string>();
            dic["productid-english"] = "english";
            return dic;
        }

        private static void OnCurrentLanguageIdChanged()
        {
            CurrentLanguageIdChanged?.Invoke(null, EventArgs.Empty);
        }
    }
}

namespace System.Data.CloudResources.Common
{
    using System.Collections.Generic;

    /// <summary>
    /// 默认创建 Key 忽略大小写的字典。
    /// <para>
    /// 如果 <see cref="TValue"/> 是 string ,
    /// 向本对象对应的配置文件添加(或删除)成员,
    /// 本对象会添加(或删除)成员
    /// </para>
    /// <para>
    /// 如果 <see cref="TValue"/> 是类型对象(例如 <see cref="KeyDictionary{TValue}"/>),
    /// 向本对象对应的配置文件添加(或删除)成员,
    /// 本对象会添加(或不会删除)成员。
    /// </para>
    /// </summary>
    /// <typeparam name="TValue"></typeparam>
    public class KeyDictionary<TValue> : Dictionary<string, TValue>
    {
        public KeyDictionary() : base(KeyInfo.DefaultCapacity, KeyInfo.DefaultKeyComparer)
        {
        }

        public KeyDictionary(int capacity) : base(capacity, KeyInfo.DefaultKeyComparer)
        {
        }

        public KeyDictionary(IDictionary<string, TValue> dictionary) : base(dictionary, KeyInfo.DefaultKeyComparer)
        {
        }

        public KeyDictionary(int capacity, IEqualityComparer<string> comparer) : base(capacity, comparer)
        {
        }
    }
}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值