2012-11-29 41 views
0

有人建议使用反射来实现此目的。我使用的方法很好,但是超过80万次迭代,我得出了明显的结论(大多数已经出现),反射并没有削减它。比较两个物体属性的最快方法

这里是我的助手类的一部分:

public static class Helper 
{ 

    public static string[] ignoredProperties = { "EntityState", 
                "EntityKey", 
                "Prop1", 
                "Prop2", 
                "Whatever", 

               }; 

    /// <summary> 
    /// Check if properties of two objects are the same. Bypasses specified properties. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="first"></param> 
    /// <param name="other"></param> 
    /// <param name="ignoreProperties"></param> 
    /// <returns></returns> 
    public static bool PropertiesEquals<T>(this T first, T other, string[] ignoreProperties) 
    { 
     var propertyInfos = first.GetType().GetProperties(); 
     foreach (PropertyInfo propertyInfo in propertyInfos) 
     { 
      //Faster with custom method ? Nah... 
      //if (FindElementIndex(ignoreProperties, propertyInfo.Name) < 0) 
      //Probably faster if hardcoded.... Nah, not really either... 
      //if (propertyInfo.Name != "EntityKey" && propertyInfo.Name != "EntityState" && propertyInfo.Name != "Group_ID" && propertyInfo.Name != "Import_status") 
      if (Array.IndexOf(ignoreProperties, propertyInfo.Name) < 0) 
       if (!Equals(propertyInfo.GetValue(first, null), propertyInfo.GetValue(other, null))) 
        return false; 
     } 
     return true; 
    } 

    public static int FindElementIndex(string[] input, string value) 
    { 
     int arraySize = input.Length - 1; 
     Type valueType = value.GetType(); 

     for (int x = 0; x <= arraySize; x++) 
     { 
      if (input[x] == value) 
       return x; 
     } 

     return -1; 
    } 

的问题是,根据类型的对象,最多可以有50级性能检查。呃...所以我真的不能做一堆如果在那里。

有什么办法可以加快这一点吗?

谢谢。

+0

解决方法:使用Equals方法并为每个类重写它以实现该属性比较(不反射)。 – Keith

回答

1

有什么办法可以加快这一点吗?

绝对。如果您要为不同的对象多次获取相同的属性,请为每个属性创建一个委托(请参阅this blog post,前面我已经介绍了一些示例),或者使用像Hyperdescriptor这样的项目。

(作为.NET 3.5,另辟蹊径,开创委托是使用表达式树和编译它们。)

+0

你的博客文章看起来很有趣。我肯定肯定会读到的。但是,我需要手动创建这些委托,还是可以根据要比较的对象类型动态创建它们? –

+0

@Francis:您可以合理轻松地动态创建它们。 –

2

您可以使用Reflection.Emit动态创建比较方法,然后只是简单地运行它。代码将被打乱并运行相当快。

有一个缺点 - 你必须知道IL的工作原理。

+0

我觉得这有点相同胡同http://stackoverflow.com/a/9607001/731678 –

0

你可以建立一个Expression指定哪些属性应该进行比较。然后,您可以将它编译为一个lambda表达式,并使用它将项目与委托调用的性能进行比较。

相关问题