使用反射的对象审核



又是我!:)

我的任务是创建一个系统来审计内部对象,我的第一次迭代不灵活,速度也很慢,所以我希望重写它,并真正让它按应有的方式工作。

这方面的性能需要尽可能完美,审核代码可能会在保存时在系统中的每个对象上运行。。

下面的代码是我到目前为止所做的——我已经使用visual studio工具对其进行了分析,我认为在这一过程中我已经删除了相当多可能的性能命中率。。

我真正想从你们那里得到的是回顾这一点,并提出任何可能的改进。CreateObjectFromHistory方法不需要像其他方法那样具有性能,它几乎永远不会被调用,这也毫无价值。

此外,他们的keyvaluepair保存是我无法控制的。

任何帮助都是非常棒的。。

干杯:)

//墙o代码即将出现。。

    public static void AuditObject(ITraceable obj)
    {
        if (obj == null)
            return;
        IEnumerable<PropertyInfo> properties = GetPropertyInfo(obj);
        List<SerializeableKeyValuePair<string, object>> kvpList =
            new List<SerializeableKeyValuePair<string, object>>();
        foreach (PropertyInfo property in properties)
        {
            SerializeableKeyValuePair<string, object> thisValue = new SerializeableKeyValuePair<string, object>();
            thisValue.Key = property.Name;
            thisValue.Value = GetPropertyValue(obj, property);
            if (thisValue.Value != null)
                kvpList.Add(thisValue);
        }
        TestObject o = CreateObjectFromHistory<TestObject>(kvpList);
    }
    public static T CreateObjectFromHistory<T>(List<SerializeableKeyValuePair<string, object>> history)
        where T : class, ITraceable
    {
        T historicalObject = Activator.CreateInstance<T>();
        Dictionary<string, PropertyInfo> propertys = GetPropertysAsDictionary(historicalObject);
        foreach (SerializeableKeyValuePair<string, object> kvp in history)
        {
            if (!propertys.ContainsKey(kvp.Key))
                continue;
            PropertyInfo prop = propertys[kvp.Key];
            if (prop == null)
                continue;
            var value = CoerceValue(prop.PropertyType, kvp.Value);
            prop.SetValue(historicalObject, value, null);
        }
        return historicalObject;
    }
    private static object CoerceValue(Type type, object value)
    {
        if (type == typeof(string))
            return value as string;
        return null;
    }
    private static object GetPropertyValue(ITraceable obj, PropertyInfo property)
    {
        if (property.PropertyType == typeof(string))
            return GetProperyValueByType<string>(property.GetValue(obj, null));
        else if (property.PropertyType == typeof(DateTime))
            return GetProperyValueByType<DateTime>(property.GetValue(obj, null));
        return null;
    }
    private static IEnumerable<PropertyInfo> GetPropertyInfo(ITraceable obj)
    {
        List<PropertyInfo> properties;
        Type objType = obj.GetType();
        if (PropertyDictionary.TryGetValue(objType, out properties) == false)
        {
            properties = obj.GetType().GetProperties(BindingFlags.Public |
                                                     BindingFlags.Instance).ToList();
            properties.RemoveAll(p => IgnoreProperty(p.GetCustomAttributes(typeof(DoNoTraceAttribute), false)));
            PropertyDictionary.Add(objType, properties);
        }
        return properties;
    }
    private static Dictionary<string, PropertyInfo> GetPropertysAsDictionary(ITraceable obj)
    {
        return GetPropertyInfo(obj).ToDictionary(pro => pro.Name);
    }
    private static object GetProperyValueByType<T>(object value)
    {
        T actualType = (T)value;
        if (actualType.Equals(default(T)))
            return default(T);
        //this will need further implementation
        return (T)value;
    }
    private static bool IgnoreProperty(IEnumerable<object> p)
    {
        return p.AsParallel().OfType<DoNoTraceAttribute>().Any();
    }

更新的代码;

   private static IEnumerable<PropertyInfo> GetPropertyInfo(ITraceable obj)
    {
        List<PropertyInfo> properties;
        Type objType = obj.GetType();
        if (PropertyDictionary.TryGetValue(objType, out properties) == false)
        {
            properties = obj.GetType().GetProperties(BindingFlags.Public |
                                                     BindingFlags.Instance).ToList();
            properties.RemoveAll(p => Attribute.IsDefined(p, typeof(DoNoTraceAttribute)));
            PropertyDictionary.Add(objType, properties);
        }
        return properties;
    }

这个看起来更好吗?

如果在运行时使用PropertyInfo.GetValue(),性能总是很慢。为了获得良好的性能(尤其是在查看大量对象时),您需要查看ILGeneratorExpression之类的内容,或者您可以使用FastMember之类的内容并通过prop.Name访问值。我真的不认为IgnoreProperty实现得很好——你应该看看这里的Attribute.IsDefined;不需要LINQ,不需要Parallel,也不需要具体化属性。

相关内容

  • 没有找到相关文章

最新更新