jfin3204
jfin3204

Reputation: 709

Passing Func to method where the func needs parameters from inside method

So I have some sorting logic that I need to use all over the place, so I thought I'd try and create a generic method that I could call and not have to copy and paste the code 30 times.

This is what I currently have for the method

public static ICollection<T> SortBySections<T>(this IEnumerable<T> objectsToSort, IEnumerable<SECTION_ORDER> sections, Func<T, bool> ascendingPredicate, Func<T, object> ascendingOrder, Func<T, bool> descendingPredicate, Func<T, object> descendingOrder, Func<T, bool> missingItemPredicate)                                                                                                                                                                                                                                                                                  
    {
        List<T> results = new List<T>();
        foreach (var sec in sections)
        {
            if (sec.MP_DIRECTION_C == "A")
            {
                results.AddRange(objectsToSort
                    .Where(ascendingPredicate)
                    .OrderBy(ascendingOrder));
            }
            else
            {
                results.AddRange(objectsToSort
                    .Where(descendingPredicate)
                    .OrderByDescending(descendingOrder));
            }
        }

        if (results.Count < objectsToSort.Count())
        {
            foreach (var item in objectsToSort)
            {
                var missing = results.
                    Where(missingItemPredicate).
                    FirstOrDefault();

                if (missing == null)
                {
                    results.Add(item);
                }
            }
        }
        return results;
    }

I am trying to call it like this

var results = equalities.SortBySections<StationEquality>(
                TimetableHelper.GetSections(subdivCode),
                new Func<StationEquality, bool>((rec) => rec.FromStation.SECTION_I == sec.SECTION_NUMBER_I && rec.FromStation.MP_PREFIX_I == sec.MP_PREFIX_I && rec.FromStation.MP_NUMBER_I >= sec.BEGIN_MP_NUMBER_I && rec.FromStation.MP_NUMBER_I <= sec.END_MP_NUMBER_I),
                new Func<StationEquality, object>((rec) => rec.FromStation.MP_NUMBER_I),
                new Func<StationEquality, bool>((rec) => rec.FromStation.SECTION_I == sec.SECTION_NUMBER_I && rec.FromStation.MP_PREFIX_I == sec.MP_PREFIX_I && rec.FromStation.MP_NUMBER_I >= sec.BEGIN_MP_NUMBER_I && rec.FromStation.MP_NUMBER_I <= sec.END_MP_NUMBER_I),
                new Func<StationEquality, object>((rec) => rec.FromStation.MP_NUMBER_I),
                new Func<StationEquality, bool>((rec) => rec.FromStation.STATION_I == rec.FromStation.STATION_I));

Is this even possible? the Sec parameter doesn't exist outside the extension method. Any help or would be appreciated. Thanks.

Upvotes: 0

Views: 147

Answers (1)

Matt Houser
Matt Houser

Reputation: 36073

Change your parameter Funcs to take 2 input parameters: rec and sec.

new Func<StationEquality, StationEquality, bool>((rec, sec) => ... )

Then inside your method, don't call the predicate directly. Instead, wrap it in another predicate passing the supplied rec parameter along with your sec parameter. For example:

.Where((rec) => ascendingPredicate(rec, sec))

I have not compiled nor tested this.

Upvotes: 1

Related Questions