Staly Staly - 1 month ago 8
C# Question

Add Contains to existing Func<T, object> property

I am trying to create Contains clause to existing Func properties lists, but I don't know how to attach it to previously passed properties list.

public static List<Func<T, bool>> GetPropertyWhereClauses<T>(List<Func<T, object>> properties, string queryPhrase)
{
var whereClauses = new List<Func<T, bool>>();

foreach (var property in properties)
{
/// how to add Contains to existing property Func<T, object> ?
whereClauses.Add(property.Contains(queryPhrase));
}

return whereClauses;
}


How to add that? I tried to use some Expression.Call but it doesn't take Func as parameter.

Answer

If you just want to convert every Func<T, object> to Func<T, bool> if the first func return object casted to string contains the queryPhrase you can do this:

public static List<Func<T, bool>> GetPropertyWhereClauses<T>(List<Func<T, object>> funcs, string queryPhrase)
{
    var whereClauses = new List<Func<T, bool>>();
    foreach (var func in funcs)
    {
        whereClauses.Add(o => func(o).ToString().Contains(queryPhrase));
    }
    return whereClauses;
}

Or better with LINQ:

 public static List<Func<T, bool>> GetPropertyWhereClauses<T>(List<Func<T, object>> funcs, string queryPhrase)
{
    return funcs.Select(func => new Func<T, bool>(o => func(o).ToString().Contains(queryPhrase)).ToList();
}

If the reutrn object is actually a list and not a string you can check if queryPhrase is a part of the list in a similar way:

public static List<Func<T, bool>> GetPropertyWhereClauses<T>(List<Func<T, object>> funcs, string queryPhrase)
{
    return funcs.Select(func => new Func<T, bool>(o => ((List<string>)func(o)).Contains(queryPhrase)).ToList();
}

It is not the best idea to make your func return tpye an object if you can chage it to the real type you are expecting to, it will save you all the redundant casting.