Barak Barak - 1 month ago 8
C# Question

How to reuse property fetched using Reflection

private static string GenerateStr<T>(IList<T> obj, string propName)
{
string str = string.Empty;
foreach(var o in obj)
{
str += o.GetType().GetProperty(propName).GetValue(o, null);
//is there a way to only call above line once, then call
// str =+ o.myStrProp over the course of the iteration?

}
return str;
}


Is there a way to be able to reuse the fetched property to refrain from relying on Reflection to do it again for me. Thanks!

Answer

What you acutally asked for

Well, if you want to stick to the methods signature (string: List<T>, string) then you at least could reuse the fetched PropertyInfo like that:

private static string GenerateStr<T>(IEnumerable<T> obj, string propName)
{
    var propertyInfo = typeof(T).GetProperty(propName);
    string str = string.Empty;

    foreach(var o in obj)
    {
        str += propertyInfo.GetValue(o, null);
    }

    return str;
}

This can even be shortened using LINQ:

private static string GenerateStr<T>(IEnumerable<T> list, string propName)
    {
        var propertyInfo = typeof(T).GetProperty(propName);

        return string.Concat(list.Select(o => propertyInfo.GetValue(o, null)));
    }

IMO Better Approach

Another and maybe even better way would be to pass sth. like a Member Expression instead of a string as the second argument:

private string GenerateStrBetter<T>(IEnumerable<T> list, Func<T, object> func)
{
    var res = string.Empty;

    foreach (var item in list)
    {
        res += func(item).ToString();
    }

    return res;
}

This should be even faster since it doesn't use reflection at all. Also, it can be rewritten to a one-liner ;) :

private string GenerateStrBetter<T>(IEnumerable<T> list, Func<T, object> func)
{
    return string.Concat(list.Select(item => func(item).ToString()));
}

Usage

var result = GenerateStrBetter(list, item => item.Text);

Not only is this faster, it also supports you during development by applying IntelliSense and avoiding Magic strings which migth be forgotten once somebody refactores your Property-Names or sth.