24

I have several methods in an application I'm working on loaded with optional parameters, some of which are enums. Currently, in order to do that I'm writing methods with a similar type of signature:

public void SomeMethod(string myFirstParam = "", string mySecondParam = "", MyEnum myThirdParam = (MyEnum )(-1)){

     if (myThirdParam != (MyEnum ) (-1))
     {
          //do something with it
     }
}

So my first question is, is there some pitfall to this approach I haven't realized, but in time will become painfully aware of, and secondly, is there a more proper - or at least elegant solution to it?

I should say that we control the input to this method, it's used internally, so I'm not worried about someone casting in a value of -1 to gum up the works.

El Kabong
  • 717
  • 1
  • 8
  • 15
  • Why not adding an extra value to your MyEnum like 'MyEnum.DEFAULT'? So you don't need to cast -1. – Soony Feb 07 '14 at 00:54
  • I agree. Better than making a nullable param and having to .HasValue or .Value all over the place, just give the enum an "UNKNOWN" value. – djcrabhat Feb 07 '14 at 00:58
  • Related: https://stackoverflow.com/questions/1795657/c-sharp-enums-nullable-or-unknown-value?noredirect=1&lq=1 – user202729 Oct 10 '18 at 14:43

3 Answers3

29

I would suggest using nullable enum in this situation, like this:

public void SomeMethod(string myFirstParam = "", 
                       string mySecondParam = "", 
                       MyEnum? myThirdParam = null)
{
   if (myThirdParam.HasValue)
   {
      var enumValue = myThirdParam.Value;
      //do something with it
   }
}

and you can use it like this:

SomeMethod(myThirdParam: MyEnum.Something);
JleruOHeP
  • 10,106
  • 3
  • 45
  • 71
  • 1
    @JonathonReinhart - what would you suggest as an alternative? – El Kabong Feb 07 '14 at 01:07
  • @JonathonReinhart: Maybe I misunderstand the nuances how nullable types work, but I don't believe _boxing_ has anything to do with this. EDIT: However, I'm opposed to using nullables in this case because it's more like a _magic value._ – Chris Sinclair Feb 07 '14 at 01:24
21

Make sure your enum has a default value (equal to zero), that means "none" or "invalid". This would be an appropriate value for your optional parameter's default value.

This is recommended by Microsoft Code Analysis as well, CA1008: Enums should have zero value.

For example:

enum SpeakerType
{
    None = 0,
    Woofer,
    Midrange
    Tweeter
}

This way the default keyword provides a value that is sane, but doesn't unintentionally refer to something you don't want it to.


As an example, the BCL uses this same concept. The number of stop bits to use for a SerialPort is defined by the StopBits enum:

public enum StopBits
{
  None,
  One,
  Two,
  OnePointFive,
}

However the None value is invalid. In fact,

The SerialPort class throws an ArgumentOutOfRangeException exception when you set the StopBits property to None.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • I know others have suggested just using a default value - but this was the most thorough and compelling answer so I'm going to accept this one, thanks for the help guys. – El Kabong Feb 07 '14 at 01:19
  • This answer is no help if you are using an enum from some library and want to set the default to something other than the default in the enum. I suppose there's just no way to do it unless you make your own enum that mimicks the one in the library. – AndrewBenjamin Nov 07 '16 at 22:40
  • With this solution you can write `SomeMethod(string myFirstParam = "", string mySecondParam = "", MyEnum myThirdParam = default(MyEnum)){ if (myThirdParam != MyEnum.None){ /*do something with it */} }` – mems Jul 08 '22 at 09:58
0

What about :

enum MyEnum {
   MISSING = -1,
   FirstValue,
   SecondValue,
   ...
}

public void SomeMethod(string myFirstParam = "", string mySecondParam = "", MyEnum myThirdParam = MISSING) {
     if (myThirdParam != MISSING)
     {
          //do something with it
     }
} 
Esko
  • 4,109
  • 2
  • 22
  • 37
Mark Bertenshaw
  • 5,594
  • 2
  • 27
  • 40
  • The reason my answer is superior to this one is that a variable of this type will default to `FirstValue` instead of `MISSING` as you'd probably intended. – Jonathon Reinhart Sep 20 '16 at 12:25