我有一个IEnumerable<MyBaseType>
类型的列表,我正在尝试创建一个额外的where子句来检索列表中的特定项目。特定值仅存在于子类型MyFirstType和MySecondType上。不在MyBaseType上。
是否可以创建表达式......
MyList.Where(b => (b is MyFirstType || (b is MySecondType)) && b.SpecificValue == message.SpecificValue);
上面不起作用,因为b是MyBaseType类型,而那里不存在SpecificValue。另请注意,我确实有另一个没有SpecificValue的子类型MyThirdType。
做我想做的工作是什么......
foreach (dynamic u in MyList)
{
if (u is MyFirstType || u is MySecondType)
{
if (u.SpecificValue == message.SpecificValue)
{
//Extracted code goes here
break;
}
}
}
任何人都知道如何为上述场景创建一个linq表达式?
答案 0 :(得分:3)
也许有一个更好的解决方案,但正如我所看到的,这可以运作得很好......如果你不介意表现。
那么,首先声明一个界面:
public interface IMySpecialType
{
object SpecificValue {get; set;} //you didn't specify what type this is
//all your other relevant properties which first and second types have in common
}
然后,使MyFirstType和MySecondType派生自此接口:
public class MyFirstType : MyBaseType, IMySpecialType
{
//snipet
}
public class MyFirstType : MySecondType, IMySpecialType
{
//snipet
}
然后,过滤并施放:
MyList
.Where(b => (b is MyFirstType) || (b is MySecondType))
.Cast<IMySpecialType>()
.Where(b => b.SpecificValue == message.SpecificValue);
//do something
答案 1 :(得分:1)
将代码直接转换为Linq where子句
string messageValue = "foo";
var result = baseList.Where(item =>
{
dynamic c = item;
if(item is MyFirstType || item is MySecondType)
{
if( c.SpecificValue == messageValue)
return true;
}
return false;
});
这需要使用动态来测试类的类型,但和 - 所以你也可以直接将项目转换为MyFirstType
或MySecondType
。
另一种方法是使用反射来检查属性是否存在,使用这种方法,只要他们拥有您感兴趣的属性,就不依赖于项目的实际类型:
string messageValue = "foo";
var result = baseList.Where( item =>
{
var prop = item.GetType().GetProperty("SpecificValue");
if (prop != null && prop.GetValue(item, null) == messageValue)
return true;
else return false;
});
如果修改类层次结构是一个选项,您可以让MyFirstType
或MySecondType
实现一个包含该属性的接口,那么您可以在Linq查询中使用OfType()
:
interface ISpecific
{
string SpecificValue { get; set; }
}
class MyFirstType : MyBase, ISpecific
{
public string SpecificValue { get; set; }
}
...
string messageValue = "foo";
var result = baseList.OfType<ISpecific>()
.Where(item => item.SpecificValue == messageValue);
答案 2 :(得分:0)
更简单的方法是创建一个界面来标记具有此属性的所有类 SpecificValue 。那是一场儿童游戏:
static void Main(string[] args)
{
List<MyBaseType> MyList = new List<MyBaseType>();
ISpecificValue message = new MyFirstType();
MyList.OfType<ISpecificValue>().Where(b => b.SpecificValue == message.SpecificValue);
}
}
class MyBaseType { }
interface ISpecificValue { string SpecificValue { get; set; } }
class MyFirstType : MyBaseType, ISpecificValue
{
public string SpecificValue;
}
class MySecondType : MyBaseType, ISpecificValue
{
public string SpecificValue;
}