2012-11-29 44 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表達式,並使用它將項目與委託調用的性能進行比較。

相關問題