I am building a command-line .exe that can apply several operations on a PDF file (add text, images, resize, crop, etc).Currently, my Program.cs looks a bit like this (it uses CommandLineParser):switch (invokedVerb){    case barcode:        Operations.BarcodeOperations.AddBarCode(options.AddBarcodeVerb);        break;    case addblankpage:        Operations.PageOperations.AddBlankPage(options.AddBlankPageVerb);        break;}As you can see, I have split the operations into several XXXOperations classes, each of them having very similar instructions:public static void AddStuff(StuffOptions options){    Logging.Log(here is a bunch of logging);    // here sometimes there is some action-specific code but not often    using (DocWrapper doc = new DocWrapper(options.File)) // this is in all actions    {        foreach (int page in doc.GetPagesToModify(options.Pages)) // this is in most actions        {            // call some stuff on the doc instance        }        doc.Save(options.OutputFile); // this is in all actions    }}So, all actions create a new instance of DocWrapper, most of them loop on its pages (but I could modify the actions so that all of them do), and all of them save, but each of them do a different set of actions inside it.How could I refactor this code so that the DocWrapper instantiation, the pages loop and the save are in a single place, but I can specify custom code inside the loop?I'm thinking of using delegates to define my actions, but I have no idea where to start, since I'm not very familiar with them. I'm also considering inheriting from an abstract class that implements the loop and abstracts a DoWork method, called inside the loop and implemented in the XXXOperations class, but since I don't know delegates, I'm not sure which is more adapted to the situation.
Command-line program for applying several operations on a PDF file
c#;delegates
Here is what I have done so far:I have created a Worker class with my redundant code:public static void DoWorkOnPages(IProgramOptions options, Action<DocWrapper, int> actions){    using (DocWrapper doc = new DocWrapper(options.File))    {        foreach (int page in doc.GetPagesToModify(options.Pages).OrderBy(p => p))        {            actions(doc, page);        }        doc.Save(options.OutputFile);    }}And in each XXXOperations class my methods calls it like this:public static void AddStuff(StuffOptions options){    Logging.Log(Here is a magnificient function);    // example of code that is different from other operations    int someVar = 0;    using (Image barcode = CreateBarcodeImage(someParameters))    {        Worker.DoWorkOnPages(options, (doc, page) =>            {                doc.SetPage(page);                doc.AddImage(barcode);                doc.DoSomething(options.SomeProperty, someVar);                someVar++;            });    }}Obviously, for in the operations that have a very different behavior, I had to duplicate some code, but I guess it can't be helped.If you come up with a more elegant, more simple, more powerful solution or just a different one, I'll gladly upvote it.