我试图概括一个重复检查器函数,该函数根据对象的类型检查该类具有的属性(在配置中提供)是否等于另一个列表中的属性。
我决定创建一个Dictionary,该字典将接受键的类型字符串(Book,Author,Shop等)和需要相等的属性数组。
词典实体示例:
"Book", ["Title", "CoverImage", "NumberOfPages"]
"Author", ["Name", "Address", "SomethingElse"]
然后,我将一个对象传递给函数,并使用Reflection获取类型的名称...
obj.GetType().Name;
...,然后我用它从Dictionary中获取正确的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();
答案 0 :(得分:2)
请尝试避免反射,因为它会减慢您的应用程序的速度。另外,您可以创建一个字典并将所有比较器放入其中:
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)));
答案 1 :(得分:0)
一个更好的解决方案是创建将标记属性的自定义属性。然后在类中重写默认方法Equals,该方法将获取具有此属性的所有属性并返回相等性。