Some object types require a lot of actions to create them. Constructor with big count of parameters — not so good idea.

Let’s see builder pattern on example. We have report forms class with several parameters — start report date, finish report date, organization name, checkbox about comparing data with last year. You can’t change these parameters from other assemblies. We can create extensions methods for changing these fields. It will be non-classic pattern realization, but userful.

    public class Report
    {
        public DateTime DateFrom { get; internal set; } = new DateTime(DateTime.Now.Year, 1, 1);
        public DateTime DateTo { get; internal set; } = DateTime.Today;
        public string Organization { get; internal set; } = "current";
        public bool CompareWithLastYear { get; internal set; } = false;
        public string ExportFormat { get; internal set; } = "pdf";

        public void Run()
        {
            Console.WriteLine($"From: {DateFrom.ToShortDateString()}");
            Console.WriteLine($"To: {DateTo.ToShortDateString()}");
            Console.WriteLine($"Org: {Organization}");
            Console.WriteLine($"Compare with last year: {CompareWithLastYear.ToString()}");
            Console.WriteLine($"Export format: {ExportFormat}");

        }
    }

Report might has more than 10 parameters.. Let’s create class ReportBuilder with extension methods. Also we can add a simple check for DateTo parameter. It should be less than current date.

    public static class ReportBuilder
    {
        public static Report DateFrom(this Report report, DateTime dateFrom)
        {
            report.DateFrom = dateFrom;
            return report;
        }
        public static Report DateTo(this Report report, DateTime dateTo)
        {
            if (dateTo > DateTime.Today) report.DateTo = DateTime.Today;
            report.DateTo = dateTo;
            return report;
        }
        public static Report Organization(this Report report, string orgName)
        {
            report.Organization = orgName;
            return report;
        }
        public static Report CompareWithLastYear(this Report report, bool compareWithLastYear)
        {
            report.CompareWithLastYear = compareWithLastYear;
            return report;
        }
        public static Report ExportFormat(this Report report, string exportFormat)
        {
            report.ExportFormat = exportFormat;
            return report;
        }
    }

You can ask me, why this realization is so complicated? And you are right, if your report is not so big, it is not part of big system e.t.c. But. When we talk about large report system with a lot of parameters, difference export types, we should build strong frame or may be durable base for our system. And in this case, after months or years, you or your college can easily extend current functional.

Let’s see how elegant we can create report parameters in compare to standard constructor.

    Report report = new Report();
    report.DateFrom(DateTime.Parse("2021-03-01"))
          .DateTo(DateTime.Parse("2021-03-30"))
          .ExportFormat("docx");

    report.Run();

Standard variant not so beatifull:

Report report = new Report (DateTime.Parse("2021-03-01"),DateTime.Parse("2021-04-01"),"",false,"docx");