I'm building a library which contains a series of methods, each of which has several overloads which I'm trying to simplify.

Many of the methods have recurring overload options. For example

AddString(string option1)
AddString(string option1, int option2)
AddString(string option1, int option2, bool option3)

AddArray(string option1)
AddArray(string option1, int option2)
AddArray(string option1, int option2, bool option3)

Now, I know that I can specify those as default parameters - parameters with a specified default value. I don't want to do this because I want the defaults to be configurable from project to project, or even from caller to caller.

I also realise that I could build an Options object which has the (configurable) defaults, and the user could pass an instance of that to another overload like so

var options = new Options();
options.OptionProperty1 = "A new string";
AddString(options);

But what I'd prefer is to have a static Options object which contained the defaults for all the parameters, and somehow specify only the changes in an inline call, like so

AddString(options => options.Set(
                            OptionProperty1 = "A string",
                            OptionProperty2 = 1,
                            OptionProperty3 = true
                        ));

Is this possible, and if so then what would the method signature look like?

有帮助吗?

解决方案

In order to have a Set method like you're after it would have to have a parameter for each option you wanted to set, which will probably get unwieldy after time,

You can opt for a fluent interface which should give you want you want. For example:

class Options
{
  Options Option1(string value)
  {
    m_Option1 = value;
    return this;
  }

  Options Option2(int value)
  {
    m_Option2 = value;
    return this;
  }
}

Now AddString would look like this:

AddString(options = > options.Option1("A String").Option2(1)));

And the implementation of AddString would look like this:

public void AddString(Action<Options> optionConfig)
{
  var options = new Options();
  optionConfig(options);

  // rest of method
}

Alternatively you could have the caller create the Options instance. This would allow them to set the properties directly:

class Options
{
  public string Option1{get;set;}
  public int Option2{get;set;}
}

And now the caller can say:

AddString(() = > new Options{Option1="A String", Option2=1});

Where AddString looks like this:

public AddString(Func<Options> optionsCreator)
{
  Options options = optionsCreator();

  // rest of method
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top