我需要創建一個物件“工廠”,其作業方式如下:
- 接受匹配物件型別的串列。
- 比較串列中的每個屬性值以查看它們是否匹配。
- 回傳該物件型別的新單個實體,僅設定匹配的欄位。
(為簡單起見,我們可以假設所有屬性都是字串)
例如,從此人員物件串列中:
Person1 { Name: "Bob", Job: "Policeman", Location: "London" }
Person2 { Name: "John", Job: "Dentist", Location: "Florida" }
Person3 { Name: "Mike", Job: "Dentist", Location: "London" }
Person4 { Name: "Fred", Job: "Doctor", Location: "London" }
如果我傳入一個包含人 2 和 3 的串列,它將回傳一個新人,如下所示:
Name: "No Match", Job: "Dentist", Location "No Match"
如果我通過人 3 和 4,它將回傳一個新人:
Name: "No Match", Job: "No Match", Location "London"
到目前為止......
使用這個 SO 問題的答案:
如何檢查所有串列項是否具有相同的值并回傳它,或者如果它們沒有則回傳“otherValue”?
我可以讓這個 LINQ 為單個已知物件作業,但我需要它是通用的。
這僅涵蓋一個特定屬性,但我的物件有 30 多個屬性。
var otherValue="No Match"
var matchingVal= people.First().Job;
return people.All(x=>x.Job== matchingVal) ? matchingVal: otherValue;
I am also aware I can use reflection to get a list of properties in my object. But how to combine all of that into a single 'factory' is beyond by comprehension.
I don't think this is a unique problem but I cannot find a complete solution in any of my searching. Maybe there is already a Nuget package out there that can help me?
All advice gratefully received.
uj5u.com熱心網友回復:
您的輸入是某種特定型別物件的列舉,您必須創建一個相同型別的物件,其中所有屬性都已填充,所有值都相同。這可以通過以下方式完成:
private static T GetCommonProperties<T>(IEnumerable<T> source) where T : new()
{
var first = true;
var common = new T();
var props = typeof(T).GetProperties();
foreach (var item in source)
{
if (first)
{
first = false;
foreach (var prop in props)
{
var value = prop.GetValue(item, null);
prop.SetValue(common, value);
}
}
else
{
foreach (var prop in props)
{
var itemValue = prop.GetValue(item, null);
var commonValue = prop.GetValue(common, null);
if ((dynamic)itemValue != (dynamic)commonValue)
{
prop.SetValue(common, GetDefault(prop.PropertyType));
}
}
}
}
return common;
}
給定的方法并不是真正的最佳方法,因為它使用dynamic技巧來解決裝箱值的比較問題。也可以通過這種通用方法來實作特定型別的默認值:
private static object GetDefault(Type t)
{
return typeof(Program)
.GetMethod(nameof(GetDefaultValue), BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(t)
.Invoke(null, null);
}
private static T GetDefaultValue<T>()
{
return default;
}
但是也可以提供一個 switch 陳述句,或者Dictionary<Type, object>如果沒有可用的匹配則回傳所需的默認值。
Last but not least, another possible performance improvement would be to remove all PropertyInfo entries from the props variable, cause for any next upcoming object, this check is not necessary anymore and the same way, the loop could be early exited, when no more props are available anymore.
A working example can be found here.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/445460.html
標籤:c# linq reflection linq-to-objects
上一篇:用自己的屬性替換字典鍵
