4ndy
4ndy

Reputation: 600

C# not passing parameters if those parameters are optional

I am hoping that this is a simple question, and it's just my brain that is missing that final link. And if there is another q&a elsewhere, please point me there and close this... but I couldn't find it anywhere.

Here is the gist:

I have a class with a method with optional parameters, something along the lines of

public class Test
{
    public void Method(string required, string someoptionalparameter="sometext", string anotheroptionalparameter="someothertext")
    {
        // do something here with the parameters
    }
 }

So far, so good.

Now, I am going to instantiate the class and call the method in my code:

 ...
Test.Method("RequiredString");

and that will work. If I provide optional parameters, it will still work.

But how do I handle a scenario, where I do not know if an optional value is actual provided. So for instance:

...
Test.Method(requiredString,optionalString1,optionalString2);
...

What if I do not know, if the optionalString1 and optionalString2 have a value or not? Do I then need to write an override for every scenario, along the lines of...

if (optionalString1.isEmpty() && optionalString2.isEmpty())
{
     Test.Method(requiredString);
}
else if ((!optionalString1.isEmpty() && optionalString2.isEmpty())
{
     Test.Method(requiredString, optionalString1);
}
else if...

There has to be another way, and I bet it is simple and I am just having one of those Fridays... Is there something like...

Test.Method(requiredStrinig, if(!optionalString1.isEmpty())... 

Upvotes: 2

Views: 3138

Answers (3)

Use overloads instead, it gives you better semantics and in case you guess the parameters from client code you'd be sure what overload to use, besides, you'll have all the machinery in one place, check out this technique, hope this helps, regards.

class Program {

  static void Main(string[] args) {
     Work("Hi!");
  }

  private static void Work(String p1) {
     Work(p1, null, null);
  }

  private static void Work(String p1, String p2) {
     Work(p1, p2, null);
  }

  private static void Work(String p1, String p2, String p3) {         
     if ( String.IsNullOrWhiteSpace(p2) ) p2 = String.Empty;
     if ( String.IsNullOrWhiteSpace(p3) ) p3 = String.Empty;

     Console.WriteLine(String.Concat(p1, p2, p3));         
  }

}

Upvotes: -1

nikib3ro
nikib3ro

Reputation: 20606

You should invert the logic - have those optional parameters be null and then do checks in method. So in your case method should be something like:

public void Method(string required, string opt1 = null, string opt2 = null)
{
    opt1 = opt1 ?? "some default non-null value if you need it";
    opt2 = opt2 ?? "another default value, this one for opt2";

    // for those not knowing what it does ?? is basically 
    // if (opt1 == null) { opt1 = "value"; }

    //... rest of method
}

Then calling that method will be easier in outside code and the logic within the method will be able to handle null cases. Outside of method you don't need to worry about those extra parameters, i.e. you can call the method any way you want, like:

Test.Method(requiredString);
Test.Method(requiredString, "something");
Test.Method(requiredString, null, "something else");

Also as @Setsu said in comment you could do this to avoid passing null as second parameter:

Test.Method("required", opt2: "thanks @Setsu");

Upvotes: 4

Doug
Doug

Reputation: 3893

Optional parameters, are, well, optional. They seem to be a way to reduce the number of overloads you have for a method. If you receive all three parameters, you will have to decide if the second or third parameters are empty and need set to their "default" values.

My suggestion is you call your method with three strings and decide in the method if you have to change the values for string two and three. I would probably use a const or readonly instead of the default values.

Upvotes: -2

Related Questions