[英]c# How To Use .Contains on Generic IEnumerable<T>
I'm trying to create a generic method that I want to use for mixing a list of objects based off a property. 我正在尝试创建一个通用方法,该方法用于混合基于属性的对象列表。 Optionally, you can supply a list of list objects to merge some groups together.
(可选)您可以提供列表对象列表,以将某些组合并在一起。 This works fine as a non-generic method and when I code the property manually, etc.
作为非泛型方法,以及当我手动编码属性等时,此方法都可以正常工作
Method head: 方法头:
public static IEnumerable<T> MixObjectsByProperty<T>(
IEnumerable<T> objects,
string propertyName,
IEnumerable<IEnumerable<T>> groupsToMergeByProperty = null)
Snippet of the methods body: 方法主体的代码段:
groups =
(from item in objects
let propertyInfo = item.GetType().GetProperty(propertyName)
where propertyInfo != null
group item by groupsToMergeByProperty
.FirstOrDefault(ids => ids.Contains(propertyInfo.GetValue(item, null)))
//.FirstOrDefault(ids => ids.Any(propertyInfo.GetValue(item, null)))
?.First()
?? propertyInfo.GetValue(item, null)
into itemGroup
select itemGroup.ToArray())
.ToList();
As you can see, I'm having trouble using the contains method on a IEnumerable<T>
as propertyInfo.GetValue(item, null)
is returning an object. 如您所见,由于
propertyInfo.GetValue(item, null)
返回一个对象,我在IEnumerable<T>
上使用contains方法遇到了麻烦。 I've tried various casting attempts and using .Any()
instead, but I've hit a brick wall :( 我尝试了各种投射尝试,并改用
.Any()
,但是我碰到了砖墙:(
Any help will be great, thanks! 任何帮助将是巨大的,谢谢!
Also, let me know if you need any more information but I guess, in essence, all I need to know is how to use .Contains()
using <T>
. 另外,如果您需要更多信息,请告诉我,但实际上,我想我仅需要知道如何使用
<T>
使用.Contains()
。
Set them to the same type? 将它们设置为相同类型? Custom
IEqualityComparer
? 自定义
IEqualityComparer
?
I've tried various casting attempts
我尝试了各种铸造尝试
Have you tried this one? 你尝试过这个吗?
.FirstOrDefault(ids => ids.Contains((T)propertyInfo.GetValue(item, null)))
Since ids
is of type IGrouping<TKey, TElement>
where TElement
is of type T
in your case, casting the value of property to T
will allow for the comparison. 由于
ids
为IGrouping<TKey, TElement>
类型IGrouping<TKey, TElement>
其中TElement
在您的情况下为T
类型,因此将属性值强制转换为T
将允许进行比较。
Without seeing the whole method (because your type signatures clearly indicate it's not the whole method), here's an example implementation: 在没有看到整个方法的情况下(因为类型签名清楚地表明它不是整个方法),这是一个示例实现:
public class Ext
{
public static List<T[]> MixObjectsByProperty<T, TProp, U>(
IEnumerable<T> source,
Expression<Func<T, TProp>> property,
IEnumerable<IEnumerable<U>> groupsToMix = null)
where T : class
where U : TProp
{
var prop = (PropertyInfo)(property.Body as MemberExpression)?.Member;
if (prop == null) throw new ArgumentException("Couldn't determine property");
var accessor = property.Compile();
var groups =
from item in source
let value = (U)accessor(item)
group item by
groupsToMix.FirstOrDefault((ids => ids.Contains(value)))
into itemGroup
select itemGroup.ToArray();
return groups.ToList();
}
}
For the love of god stop passing property names and using reflection, the rest of Linq makes use of the gorgeous expression system, and you should too! 为了让上帝的爱停止传递属性名称和使用反射,Linq的其余部分使用了华丽的表达系统,您也应该这样做!
Ok, so I cracked it in the end. 好的,所以我最终破解了它。 I needed to add more detail in my generic method header/signature.
我需要在通用方法标题/签名中添加更多详细信息。
public static IEnumerable<T> MixObjectsByProperty<T, U>(
IEnumerable<T> objects, string propertyName, IEnumerable<IEnumerable<U>> groupsToMergeByProperty = null)
where T : class
where U : class
{
...
Note, I added class constraints which allows me to use nullable operators, etc. 注意,我添加了类约束,使我可以使用可为空的运算符,等等。
And the body became (after adding a propertyValue variable which is casted to the correct type!): 然后,主体变成了(添加了强制转换为正确类型的propertyValue变量之后):
groups =
(from item in objects
let propertyInfo = item.GetType().GetProperty(propertyName)
where propertyInfo != null
let propertyValue = (U)propertyInfo.GetValue(item, null)
group item by
groupsToMergeByProperty
.FirstOrDefault(ids => ids.Contains(propertyValue))
?.First()
?? propertyValue
into itemGroup
select itemGroup.ToArray())
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.