Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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# 使用反射的对象审计_C#_Performance_Reflection - Fatal编程技术网

C# 使用反射的对象审计

C# 使用反射的对象审计,c#,performance,reflection,C#,Performance,Reflection,又是我!:) 我的任务是创建一个审计内部对象的系统,我的第一次迭代没有灵活性,速度也很慢,所以我希望重写它,真正让它按照应该的方式工作 这方面的性能需要尽可能完美,在保存审计代码时,它们可能会在系统中的每个对象上运行 下面的代码是我迄今为止所做的工作-我已经使用visual studio工具对其进行了分析,并且我认为我已经删除了很多可能的性能影响 我真正想从你们这里得到的是回顾这一点,并提出任何可能的改进,它也毫无价值,CreateObjectFromHistory方法不需要像其他方法那样性能优

又是我!:)

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

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

下面的代码是我迄今为止所做的工作-我已经使用visual studio工具对其进行了分析,并且我认为我已经删除了很多可能的性能影响

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

还有,他们说,储蓄不是我能控制的

任何帮助都会很好

干杯:)

//墙上的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();
    }
publicstaticvoidauditobject(ITraceable obj)
{
if(obj==null)
返回;
IEnumerable properties=GetPropertyInfo(obj);
列表kvpList=
新列表();
foreach(属性中的PropertyInfo属性)
{
SerializableKeyValuePair thisValue=新的SerializableKeyValuePair();
thisValue.Key=property.Name;
thisValue.Value=GetPropertyValue(对象,属性);
if(thisValue.Value!=null)
kvpList.Add(此值);
}
TestObject o=CreateObjectFromHistory(kvpList);
}
公共静态T CreateObjectFromHistory(列表历史记录)
其中T:类,可访问
{
T historicalObject=Activator.CreateInstance();
Dictionary propertys=GetPropertysAsDictionary(历史对象);
foreach(历史记录中的SerializableKeyValuePair kvp)
{
如果(!propertys.ContainsKey(kvp.Key))
继续;
PropertyInfo prop=propertys[kvp.Key];
if(prop==null)
继续;
var值=强制值(prop.PropertyType,kvp.value);
prop.SetValue(historicalObject,value,null);
}
返回历史对象;
}
私有静态对象强制值(类型、对象值)
{
if(type==typeof(string))
以字符串形式返回值;
返回null;
}
私有静态对象GetPropertyValue(ITraceable对象,PropertyInfo属性)
{
if(property.PropertyType==typeof(string))
返回getPropertyValueByType(property.GetValue(obj,null));
else if(property.PropertyType==typeof(DateTime))
返回getPropertyValueByType(property.GetValue(obj,null));
返回null;
}
私有静态IEnumerable GetPropertyInfo(ITraceable obj)
{
列出财产;
类型objType=obj.GetType();
if(PropertyDictionary.TryGetValue(对象类型,输出属性)==false)
{
properties=obj.GetType().GetProperties(BindingFlags.Public|
BindingFlags.Instance.ToList();
RemoveAll(p=>IgnoreProperty(p.GetCustomAttributes(typeof(DoNoTraceAttribute),false));
添加(对象类型,属性);
}
归还财产;
}
私有静态字典GetPropertysAsDictionary(ITraceable obj)
{
返回GetPropertyInfo(obj.ToDictionary)(pro=>pro.Name);
}
私有静态对象GetPropertyValueByType(对象值)
{
T实际类型=(T)值;
if(actualType.Equals(默认值(T)))
返回默认值(T);
//这需要进一步实施
返回(T)值;
}
私有静态布尔IgnoreProperty(IEnumerable p)
{
返回p.AsParallel().OfType().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;
    }
私有静态IEnumerable GetPropertyInfo(ITraceable obj)
{
列出财产;
类型objType=obj.GetType();
if(PropertyDictionary.TryGetValue(对象类型,输出属性)==false)
{
properties=obj.GetType().GetProperties(BindingFlags.Public|
BindingFlags.Instance.ToList();
properties.RemoveAll(p=>Attribute.IsDefined(p,typeof(DoNoTraceAttribute));
添加(对象类型,属性);
}
归还财产;
}

这看起来更好吗?

如果在运行时使用
PropertyInfo.GetValue()
,性能将总是很慢。要获得良好的性能(尤其是查看大量对象),您需要查看类似于
ILGenerator
Expression
——或者您可以使用类似的工具并通过
prop.Name
访问值。我真的不认为
IgnoreProperty
实现得很好-您应该只看
Attribute.IsDefined
;不需要LINQ,不需要
并行
,也不需要具体化属性。

看起来
强制值
意味着您的代码只在字符串中工作….?并行指令是提高了您场景中的性能还是使其更糟?是的-目前强制值只在字符串中工作,这最终只适用于字符串、日期时间、位和guid。此外,并行确实提高了性能。。非常轻微。您能提供一个使用FastMember的样品吗?另外-请参阅更新。@Stephen-fastmember-这是怎么做的?请注意,如果您不总是处理相同类型的块,那么还有
ObjectAccessor
。它担心在内部对每个类型等进行缓存,所以您不必这样做。那
属性.已定义
用法看起来好多了.那看起来很棒-我现在就去试试。。你的Fastmember通常比我现在做的快多少