Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象转换为字典<;PropertyName,Value>;_C# - Fatal编程技术网

C# 将对象转换为字典<;PropertyName,Value>;

C# 将对象转换为字典<;PropertyName,Value>;,c#,C#,我有一个用例,其中我必须以表格的形式显示任何对象列表List objects。因此,我实现了一个函数,它以可用的格式准备数据: public static Dictionary<Guid, Dictionary<string, object>> PrepareList<T>(List<T> Items, List<string> RelevantProperties) { var res = ne

我有一个用例,其中我必须以表格的形式显示任何对象列表
List objects
。因此,我实现了一个函数,它以可用的格式准备数据:

public static Dictionary<Guid, Dictionary<string, object>> PrepareList<T>(List<T> Items, List<string> RelevantProperties)
        {
            var res = new Dictionary<Guid, Dictionary<string, object>>();
            var propDicSplitted = new Dictionary<string, List<string>>();

            foreach (string relevantProperty in RelevantProperties)
            {
                if (relevantProperty.Contains("."))
                {
                    var split = relevantProperty.Split('.');
                    if(!propDicSplitted.ContainsKey(split[0]))
                    {
                        propDicSplitted.Add(split[0], new List<string>());
                    }
                    propDicSplitted[split[0]].Add(relevantProperty);
                }
            }

            foreach (T item in Items)
            {
                var itemPropDic = item.ToDictionary();

                var itemId = (Guid)itemPropDic["ID"];
                if (!res.ContainsKey(itemId))
                {
                    res.Add(itemId, new Dictionary<string, object>());
                }

                foreach(string relevantProperty in RelevantProperties)
                {
                    if (itemPropDic.ContainsKey(relevantProperty)) { 
                        res[itemId].Add(relevantProperty, itemPropDic[relevantProperty]);
                    }
                }

                foreach(string subObjectName in propDicSplitted.Keys)
                {
                    foreach (string relevantSubProperty in propDicSplitted[subObjectName])
                    {
                        res[itemId].Add(relevantSubProperty, GetNestedPropertyValue(itemPropDic, relevantSubProperty.Split('.')));
                    }
                }

            }
            return res;
        }

        private static object GetNestedPropertyValue(IDictionary<string, object> Obj, string[] PropertiesPath)
        {
            if (PropertiesPath.Length == 1)
                return Obj[PropertiesPath[0]];

            return GetNestedPropertyValue(Obj[PropertiesPath[0]].ToDictionary(), PropertiesPath.Skip(1).ToArray());
        }

但是,问题是函数
PrepareList()
太慢,需要2分钟才能创建一个包含10000项和8个相关属性的列表。我需要一个关于如何优化这个的提示。感谢您的建议。

问题:您是否真的在表中显示了10000行?超过50行左右,大多数表都没有用处;如果要分页:只对实际显示的行运行映射步骤?或者-甚至不要运行映射步骤:大多数用于构建表的UI工具都不会这样做-它们只是获取描述符数据并直接在每个单元格中执行,而不在中间构建字典之类的东西。您是否尝试过使用秒表来定位瓶颈?每个项目的相关属性是否会改变?否则,您可以一次性获得相关属性。我用100.000项和10个相关属性(非嵌套)测试了代码,花了781ms才完成。@MarcGravel,所以你说如果我只向Datatables(例如)传递一个对象和相关列名的列表,如果没有准备正确格式的数据就应该足够了?这在这里是不可能评论的;如果你只是随意摆弄,就没有“正确的格式”——或者,同样地,所有格式都是“正确的”。如果性能是您关心的问题,“做最少的事情”是一个很好的目标,那么如果您不需要10000个字典:不创建它们吗?@RedFox以前为大约2000个项目创建过字典,这是可以的,但不适用于太多嵌套属性的字典。我想问题可能确实出在函数GetNestedPropertyValue()中的嵌套属性上
public static IDictionary<string, object> ToDictionary(this object source, bool ignoreComplexTypes = false)
        {
            return source.ToDictionary<object>(ignoreComplexTypes);
        }

        public static IDictionary<string, T> ToDictionary<T>(this object source, bool ignoreComplexTypes)
        {
            if (source == null)
                throw new ArgumentNullException("source", "Unable to convert object to a dictionary. The source object is null.");

            var dictionary = new Dictionary<string, T>();
            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
                AddPropertyToDictionary<T>(property, source, dictionary, ignoreComplexTypes);
            return dictionary;
        }

        private static void AddPropertyToDictionary<T>(PropertyDescriptor property, object source, Dictionary<string, T> dictionary, bool ignoreComplexTypes)
        {
            object value = property.GetValue(source);
            if (IsOfType<T>(value) && !(ignoreComplexTypes))
                dictionary.Add(property.Name, (T)value);
        }

        private static bool IsOfType<T>(object value)
        {
            return value is T;
        }