santi
santi

Reputation: 661

C# LINQ Expression as parameter for DataTable method

I have a LINQ expression that I wish to make it become generic :

public class GenericBudgetMatrix
    {
        public List<string> MatrixHeaders { set; get; }
        public List<GenericBudgetMatrixRow> MatrixRow { set; get; }
        public GenericBudgetMatrixRow MatrixFooterRow { set; get; }
    }

public class GenericBudgetMatrixRow
{
        public string EntityName { set; get; }
        public List<decimal> Values { set; get; }
        public decimal Total { set; get; }
}

GenericBudgetMatrix _genericBudgetMatrix = new GenericBudgetMatrix();

_genericBudgetMatrix.MatrixRow = _matrixTemplate.AsEnumerable().Select(r =>
                                    new GenericBudgetMatrixRow
                                    {
                                        EntityName = r.Field<string>(0),
                                        Values = r.ItemArray.Skip(1).Select(x => Convert.ToDecimal(x)).ToList(),
                                        Total = r.ItemArray.Skip(1).Select(x => Convert.ToDecimal(x)).Sum()
                                    }
                                    ).ToList();

I wish to make a new method to accept

r =>
     new GenericBudgetMatrixRow
     {
        EntityName = r.Field<string>(0),
        Values = r.ItemArray.Skip(1).Select(x => 
                    Convert.ToDecimal(x)).ToList(),
                    Total = r.ItemArray.Skip(1).Select(x => 
                     Convert.ToDecimal(x)).Sum()
                                        }

as a Func expression parameter.

Something like this :

public void GenericMethod(Func<expression> predicate, DataTable _matrixTemplate)
{
    _matrixTemplate.AsEnumerable().Select(predicate).ToList();
}

Any ideas that can help me build this approach?

Upvotes: 0

Views: 409

Answers (2)

santi
santi

Reputation: 661

I figured out the solution already. It is due to the Generic Type

public IEnumerable<TResult> GenericMethod(Func<DataRow, TResult> predicate, DataTable _matrixTemplate)
{
    return _matrixTemplate.AsEnumerable().Select(predicate);
}

Upvotes: 0

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37095

Select expects a Func<T, TResult>, so you should provide it as parameter to your method:

public void GenericMethod<T, TResult>(Func<T, TResult> predicate, DataTable _matrixTemplate)
{
    _matrixTemplate.AsEnumerable().Select(predicate).ToList();
}

Furthermore I guess your method should return the result of your selection, so turn it into a method returning instances of TResult(which in your case is GenericBudgetMatrixRow). Last but not least the call to ToList is obsolete as you´re doing this in your calling code anyway. Thus return an IEnumerable<TResult> instead:

public IEnumerable<TResult> GenericMethod<T, TResult>(Func<T, TResult> predicate, DataTable _matrixTemplate)
{
    return _matrixTemplate.AsEnumerable().Select(predicate);
}

Now you cann call it like this:

_genericBudgetMatrix.MatrixRow = GenericMethod(
    r => new GenericBudgetMatrixRow
        {
            EntityName = r.Field<string>(0),
            Values = r.ItemArray.Skip(1).Select(x => Convert.ToDecimal(x)).ToList(),
            Total = r.ItemArray.Skip(1).Select(x => Convert.ToDecimal(x)).Sum()
        }, 
    _matrixTemplate)
    .ToList();

Upvotes: 2

Related Questions