我有以下扩展方法
public static class ListExtensions
{
public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch)
{
foreach (T t in collection)
{
Type k = t.GetType();
PropertyInfo pi = k.GetProperty("Name");
if (pi.GetValue(t, null).Equals(stringToSearch))
{
yield return t;
}
}
}
}
它的作用是使用反射,它找到name属性,然后根据匹配的字符串过滤集合中的记录。
此方法被称为
List<FactorClass> listFC = new List<FactorClass>();
listFC.Add(new FactorClass { Name = "BKP", FactorValue="Book to price",IsGlobal =false });
listFC.Add(new FactorClass { Name = "YLD", FactorValue = "Dividend yield", IsGlobal = false });
listFC.Add(new FactorClass { Name = "EPM", FactorValue = "emp", IsGlobal = false });
listFC.Add(new FactorClass { Name = "SE", FactorValue = "something else", IsGlobal = false });
List<FactorClass> listFC1 = listFC.Search("BKP").ToList();
工作正常。
但仔细研究一下扩展方法就会发现
Type k = t.GetType();
PropertyInfo pi = k.GetProperty("Name");
实际上是在foreach循环中,实际上并不需要。我想我们可以把它带到循环之外。
但是怎么样?
提供帮助。 (C#3.0)
答案 0 :(得分:3)
以这种方式使用反射对我来说很难看。
您确定需要100%通用的“T”并且不能使用基类或接口吗?
如果我是你,我会考虑使用.Where<T>(Func<T, Boolean>)
LINQ方法而不是编写自己的搜索功能。
示例用法是:
List<FactorClass> listFC1 = listFC.Where(fc => fc.Name == "BKP").ToList();
答案 1 :(得分:2)
public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch)
{
Type k = typeof(T);
PropertyInfo pi = k.GetProperty("Name");
foreach (T t in collection)
{
if (pi.GetValue(t, null).Equals(stringToSearch))
{
yield return t;
}
}
}
答案 2 :(得分:1)
得到T的类型
Type k = typeof(T);
PropertyInfo pi = k.GetProperty("Name");
foreach (T t in collection)
{
if (pi.GetValue(t, null).Equals(stringToSearch))
{
yield return t;
}
}
答案 3 :(得分:1)
您可以执行以下操作 - 首先,您可以将泛型类型的约束设置为具有name属性的接口。如果它只能使用FactorClass,那么您实际上并不需要泛型类型 - 您可以将其作为ICollection<FactorClass>
的扩展。如果您使用接口路由(或使用非泛型版本),则只需引用该属性即可,无需进行反射。如果由于某种原因,这不起作用,你可以这样做:
var k = typeof(T);
var pi = k.GetProperty("Name");
foreach (T t in collection)
{
if (pi.GetValue(t, null).Equals(stringToSearch))
{
yield return t;
}
}
使用界面可能看起来像
public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch) where T : INameable
{
foreach (T t in collection)
{
if (string.Equals( t.Name, stringToSearch))
{
yield return t;
}
}
}
编辑:在看到@ Jeff的评论之后,如果您正在做一些比简单地检查其中一个属性的值更复杂的事情,这真的很有用。他绝对正确,使用Where
是解决该问题的更好方法。