简体   繁体   中英

How to modify delegate to set a property of its return value in certain cases

I apologize for the crappy title, I have no idea how to put this into words.

Assume the following scenario:

A Holiday struct implementing this interface:

public interface IHoliday
{
    HolidayName Name { get; }
    DateTime Date { get; }
    bool IsRegional { get; set; }
}

A HolidayCalculator class with several methods to calculate various holidays based on the given year:

public static class HolidayCalculator
{
    public static IHoliday GetAssumptionDay(int year)
    {
        CheckYear(year);
        return new Holiday(GetHolidayName(), new DateTime(year, 8, 15));
    }

    // and so on...
}

A HolidayFunc delegate and a HolidayStateMap class which inherits from Dictionary to map certain holidays to their respective states:

public delegate IHoliday HolidayFunc(int year);

public class HolidayStateMap : Dictionary<State, List<HolidayFunc>>
{
    public HolidayStateMap()
    {
        // add keys (State) with nation-wide holidays

        // add state specific holidays
        this[State.Bavaria].AddRange(new HolidayFunc[]
        {
            HolidayCalculator.GetEpiphany,
            HolidayCalculator.GetCorpusChristi,
            HolidayCalculator.GetAllSaintsDay
        });
    }
}

To get all holidays for a given state you go:

var holidayFunctions = _holidayStateMap[state];
var holidays = holidayFunctions.Select(function => function(year));

The Question:

Some holidays, in some states, are celebrated in certain regions only. Meaning Assumption Day could be celebrated in all regions of one state but only in some regions of another.

I would now like to set the IsRegional property when the delegate is invoked for state1 but not for state2. All this, without changing my current setting.

Is it possible in some way to intercept the return value ( Holiday ) of the delegate I'm calling and inject a true into the IsRegional property where necessary. Maybe by wrapping my delegate I am imagining something like this when populating the HolidayStateMap :

if (includeRegional)
{
    this[State.Bavaria].AddRange(new HolidayFunc[]
    {
        HolidayCalculator.GetAssumptionDay.AsRegional,
        HolidayCalculator.GetPeaceFestival.AsRegional
    });

    // and others...
{

which would then return the respective Holiday but with IsRegional set to true.

Going for an extension method, I'd picture the implementation to look somewhat like this:

public static IHoliday AsRegional(this HolidayFunc func, int year)
{
    var holiday = func.Invoke(year);
    holiday.IsRegional = true;
    return holiday;
}

(I know I would need an instance of the delegate for this to work)

Maybe someone can come up with a neat solution, I'm kinda stuck. Thanks in advance.

PS: I know I might be overengineering this, but well..

Oh my god.

I basically answered the question myself in the description:

(I know I would need an instance of the delegate for this to work)

The solution was:

if (includeRegional)
{
    this[State.Bavaria].AddRange(new HolidayFunc[]
    {
        new HolidayFunc(HolidayCalculator.GetAssumptionDay).AsRegional, 
        new HolidayFunc(HolidayCalculator.GetPeaceFestival).AsRegional
    });
}

Sorry for that. Thank you @Jeroen van Langen for trying though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM