List<T> objectList = GetList();
foreach (T setName in setNames)
{
List<T> list = objectList.Where(x => x.QualificationID == setName).ToList();
redisClient.SetAdd<string>("Qualification:" + setName, list.Select(x => x.ProductID).ToString());
}
在第3行中,T不包含'QualificationID'的定义,也没有可以找到接受Type T的第一个参数的扩展方法'QualificationID'。
同样在第4行, T不包含'ProductID'的定义,也没有扩展方法'ProductID'可以找到Type T的第一个参数。
我们如何使用linq过滤通用对象列表?
编辑:在指定classtype之前,发现无法在泛型方法中过滤属性值。 比如将方法扩展到,
method()其中T:ClassType
如答案和评论中所述。
答案 0 :(得分:4)
假设您的基本类型<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="imgcontainer">
<div style="background-image:url(http://placehold.it/500x340/0bf);">
Slide 1
</div>
<div style="background-image:url(http://placehold.it/500x340/f0b);">
Slide 2
</div>
<div style="background-image:url(http://placehold.it/500x340/b0f);">
Slide 3
</div>
</div>
包含公共成员BaseType
和QualificiationID
,您可以执行以下操作:
ProductID
这假设泛型类型特定于该方法。如果它是类级泛型,只需将void Foo<T>() where T : BaseType
{
List<T> objectList = GetList();
foreach (T setName in setNames)
{
List<T> list = objectList.Where(x => x.QualificationID == setName).ToList();
redisClient.SetAdd<string>("Qualification:" + setName, list.Select(x => x.ProductID).ToString());
}
}
移动到类声明中的相应位置。
作为次要问题,第二次where T : BaseType
来电的ToString()
部分可能与您认为正在进行的操作无关。 .Select
将尝试将对象转换为字符串,默认情况下将返回类型名称。这意味着所有你摆脱它的东西都是ToString
的。为了从LINQ中实际获取字符串,您必须将它提供给字符串构造函数并稍微更改一下:
"System.Linq.IEnumerable+WhereSelectEnumerableIterator`1"
答案 1 :(得分:0)
问题是您的编译器不知道T类型的对象具有QualificationId和ProductId属性。你不得不告诉编译器。
执行此操作的最通用方法是向T添加约束,通知编译器T具有这两个属性。这是在where clause
中完成的void MyFunc<T>(T obj) where T : ...
您可以放置一个您知道它具有这两个属性的基类,而不是点。更通用的是你提供一个接口。您保证,无论何时使用MyFunct
,提供的obj都是实现接口的类型T:
interface IMyInterface
{
public int QualificationId {get;}
public int ProductId {get;}
}
public void MyFunct<T>(List<T> objectList) where T: IMyInterface
{
// here you know that any T implements IMyInterface,
// and thus you can get QualificationId and ProductId
List<T> list = objectList
.Where(listElement => listElement.QualificationID == setName).ToList();
redisClient.SetAdd<string>("Qualification:" + setName,
list.Select(listElement => listElement.ProductID).ToString());
}
接口方法优于基类方法,因为只要它实现了接口,它就让你有机会使用任何T,即使它有不同的基类
作为旁注:我不确定你想用SetAdd做什么,但你的Select的结果可能是一系列ProductIds。此序列的ToString()将描述序列,而不是序列中的元素。我很确定这不是你想要的