簡體   English   中英

如何使用反射來調節多個屬性以檢查 LINQ .Where 語句中的相等性,具體取決於傳遞的類?

[英]How use Reflection to condition multiple properties to check for equality in a LINQ .Where statement, depending on what class is passed?

我試圖概括一個重復的檢查器函數,它取決於對象的類型,檢查所述類具有的屬性(在配置中提供)是否等於另一個列表中的屬性。

我決定創建一個字典,它將接受一個類型字符串作為鍵(書、作者、商店等)和一個需要相等的屬性數組。

字典條目示例:

"Book", ["Title", "CoverImage", "NumberOfPages"] 
"Author", ["Name", "Address", "SomethingElse"]

然后,我將一個對象傳遞給函數並使用反射來獲取類型的名稱......

obj.GetType().Name;

...然后我用它從字典中獲取正確的 KVP,這意味着如果我傳遞一個 Book 對象,我會得到“Book”。 然后我們使用它來通過...獲取配置

configDictionary["obj.GetType().Name"]

...它為我們提供了字符串數組,這些字符串是我們需要檢查相等性的屬性。

我已經到了我需要一些東西的部分

list.Where(x => --> for each of the strings in the array - x.GetType.GetProperty(string) && --> same for next string && same for next string

......然后我需要用......

x.Id != obj.Id

確保我們根據我們的邏輯檢查重復項(不同的 id 和所有屬性的匹配,但因此具有不同的 Id - 重復)。

結束查詢應如下所示

圖書:

someList.Where(x => 
x.Title == obj.Title 
&& x.CoverImage == obj.CoverImage 
&& x.NumberOfPages == obj.NumberOfPages 
&& x.Id != obj.Id)
.FirstOrDefault();

作者:

someList.Where(x => x.Name == obj.Name 
&& x.Address == obj.Address 
&& x.SomethingElse == obj.SomethingElse 
&& x.Id != obj.Id)FirstOrDefault();

盡量避免反射,因為它會減慢您的應用程序。 作為替代方案,您可以創建一個字典並將所有比較器放入其中:

var configDictionary = new Dictionary<string, List<Func<object, object, bool>>>
{
    {
        "Book",
        new List<Func<object, object, bool>>
        {
            (b1, b2) => ((Book)b1).Title == ((Book)b2).Title,
            (b1, b2) => ((Book)b1).CoverImage == ((Book)b2).CoverImage,
            (b1, b2) => ((Book)b1).NumberOfPages == ((Book)b2).NumberOfPages,
            (b1, b2) => ((Book)b1).Id != ((Book)b2).Id,
        }
    },
    // same for Authors
};

現在您可以在Where方法中使用它:

var typeName = obj.GetType().Name; // here we using Reflection but once per collection, not per each item
var first = someList.Where(x => configDictionary[typeName].All(f => f(x, obj))).FirstOrDefault();

此外,因為FirstOrDefault也有接受謂詞最后一行的重載可以重寫為:

var first = someList.FirstOrDefault(x => configDictionary[typeName].All(f => f(x, obj)));

更好的解決方案是創建將標記屬性的自定義屬性。 然后在類中覆蓋默認方法 Equals,它將獲取具有此屬性的所有屬性並返回相等性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM