I have the following extension method
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;
}
}
}
}
What it does is by using reflection, it finds the name property and then filteres the record from the collection based on the matching string.
This method is being called as
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();
It is working fine.
But a closer look into the extension method will reveal that
Type k = t.GetType();
PropertyInfo pi = k.GetProperty("Name");
is actually inside a foreach loop which is actually not needed. I think we can take it outside the loop.
But how?
PLease help. (C#3.0)
There’s a couple of things you could do — first you could institute a constraint on the generic type to an interface that has a name property. If it can only take a FactorClass, then you don’t really need a generic type — you could make it an extension to an
ICollection<FactorClass>. If you go the interface route (or with the non-generic version), you can simply reference the property and won’t have a need for reflection. If, for some reason, this doesn’t work you can do:using an interface it might look like
EDIT: After seeing @Jeff’s comment, this is really only useful if you’re doing something more complex than simply checking the value against one of the properties. He’s absolutely correct in that using
Whereis a better solution for that problem.