使用linq根据通用列表项的反映值筛选通用列表

使用linq根据通用列表项的反映值筛选通用列表,linq,reflection,Linq,Reflection,我有一个通用的对象列表,我想根据其中的反射值对其进行缩减 List<MyCaseObj> CasesInGroup = ....; PropertyInfo piItem = typeof(MyCaseObj).GetProperty(SomePropertyName).PropertyType.GetProperty(SomeValueMemberName); var CasesToProcess = (from csh in CasesInGroup

我有一个通用的对象列表,我想根据其中的反射值对其进行缩减

List<MyCaseObj> CasesInGroup = ....;
PropertyInfo piItem = typeof(MyCaseObj).GetProperty(SomePropertyName).PropertyType.GetProperty(SomeValueMemberName);

    var CasesToProcess = (from csh in CasesInGroup 
        where ((Guid)piItem.GetValue(piField.GetValue(csh, null), null))
            .In(fld.Items.Select(i => i.ItemID)) 
                select csh);
列出案例组=。。。。;
PropertyInfo piItem=typeof(MyCaseObj).GetProperty(SomePropertyName).PropertyType.GetProperty(SomeValueMemberName);
var CasesToProcess=(来自CasesInGroup中的csh
其中((Guid)piItem.GetValue(piField.GetValue(csh,null),null))
.In(fld.Items.Select(i=>i.ItemID))
选择csh);
然而,它揭示了特定值有时可能为null,In扩展不喜欢抛出“非静态方法需要目标”异常

添加&&(Guid)piItem.GetValue(piField.GetValue(csh,null),null)!=null不起作用,并且无论如何都会进行两次反射,这在一开始似乎并不正确,即使它确实发生了。。 有人能解释一下如何避开这个问题吗?或者也许是一个更好的方法

任何帮助、指点或诸如此类的事情都将不胜感激

谢谢

您可以替换

(Guid)piItem.GetValue(piField.GetValue(csh, null), null))

除非
有时包含
Guid.Empty
,否则它应该可以工作

另外,如果你想学习一些非常非常酷的东西,请将此表达式转换为lambda:

var myCaseType = typeof(MyCaseObj);
var param = Expression.Parameter(myCaseType);
var cond = Expression.Condition(
    Expression.NotEqual(param, Expression.Constant(null, myCaseType))
,   Expression.Property(param, "SomePropertyName")
,   Expression.Constant(Guid.Empty)
);
var lambda = (Func<MyCaseObj,Guid>)Expression.Lambda(cond, param).Compile();
你可以代替

(Guid)piItem.GetValue(piField.GetValue(csh, null), null))

除非
有时包含
Guid.Empty
,否则它应该可以工作

另外,如果你想学习一些非常非常酷的东西,请将此表达式转换为lambda:

var myCaseType = typeof(MyCaseObj);
var param = Expression.Parameter(myCaseType);
var cond = Expression.Condition(
    Expression.NotEqual(param, Expression.Constant(null, myCaseType))
,   Expression.Property(param, "SomePropertyName")
,   Expression.Constant(Guid.Empty)
);
var lambda = (Func<MyCaseObj,Guid>)Expression.Lambda(cond, param).Compile();

哈哈,当然,我总是想学一些很酷的东西,但是。。A.可以看到那里发生了什么,但不完全是b。这真的能处理fac吗?我要找的房产有点深?C一种旁白-fld.Items.Select(i=>i.ItemID).Contains(..)比在循环中的扩展pps fld快,因此:foreach(BackingSheetGroupField fld In bsg.Fields)和SomePropertyname和someValueMemberName都来自于此。。不确定在每一圈上编译这些数据是否会有很大的开销?@nat a。代码使用LINQ表达式构建表达式的表示。B你是对的,我完全错过了这两个深度-没有滚动到右侧以在OP中看到它。添加第二个间接层次是一个很好的练习:如果你能够做到这一点,你就会知道你比“某种程度上”更了解正在发生的事情。C我不知道两者的相对速度-您可能想运行一个快速的实验,看看哪一个赢。现在由于我很忙,我最终得到了casestoproces=CasesInGroup.Where(c=>fld.Items.Select(I=>I.ItemID)。包含((c!=null?(Guid)piItem.GetValue(piField.GetValue(c,null),null):Guid.Empty));不过,我还是会读一些书,非常感谢你,我当然会一直想学一些很酷的东西。。A.可以看到那里发生了什么,但不完全是b。这真的能处理fac吗?我要找的房产有点深?C一种旁白-fld.Items.Select(i=>i.ItemID).Contains(..)比在循环中的扩展pps fld快,因此:foreach(BackingSheetGroupField fld In bsg.Fields)和SomePropertyname和someValueMemberName都来自于此。。不确定在每一圈上编译这些数据是否会有很大的开销?@nat a。代码使用LINQ表达式构建表达式的表示。B你是对的,我完全错过了这两个深度-没有滚动到右侧以在OP中看到它。添加第二个间接层次是一个很好的练习:如果你能够做到这一点,你就会知道你比“某种程度上”更了解正在发生的事情。C我不知道两者的相对速度-您可能想运行一个快速的实验,看看哪一个赢。现在由于我很忙,我最终得到了casestoproces=CasesInGroup.Where(c=>fld.Items.Select(I=>I.ItemID)。包含((c!=null?(Guid)piItem.GetValue(piField.GetValue(c,null),null):Guid.Empty));不过我会读一些书,非常感谢