Search code examples
c#enumsparameter-passing

How can I limit function parameter values?


I have a function, that has an enum value as a parameter. In this specific function, I expect the enum value to only be able to have two of the four enum values. Can I limit the expected parameters?

public enum DifferenceType
{
    Identical,
    Added,
    Changed,
    Removed
}

public void DoSomething(DifferenceType difference)
{
    if( difference == DifferenceType.Added)
    {
        // do something
    }
    else // Assert the value is DifferenceType.Removed
    {
        // do something else
    }
}

I could expect a bool like IsDifferenceTypeAdded or something like that, but that feels unclean, since it doesn't imply that otherwise it can only be DifferenceType. Is there any other way that I'm not thinking of?

The enum is used at different places in our program and I can't change it. This is not a big problem, but I am curious if there is a better way of doing that.


Solution

  • There's isn't a magic bullet to solve this problem. Specifically, in the case you're describing (and without further knowledge of your actual system, of course) I would probably rather do what fana suggested in the comments and simply have a method for each supported types:

    public void DoSomethingOnAdd() {/* implementation */}
    
    public void DoSomethingOnRemove() {/* implementation */}
    

    but in a more general way, suppose you have an enum with 40 members instead of just 4, and you want the method to handle, say, 10 of these members.
    In this case, I would consider creating another enum just for this method, and add an extension method to your main enum, to translate from it to the new enum - something like this:

    public enum SupportedType
    {
        Unsupported, Added, Removed
    }
    
    static class DifferenceTypeExtensions
    {
        public static SupportedType ToSupportedType(this DifferenceType dt)
            => dt switch
            {
                DifferenceType.Added => SupportedType.Added,
                DifferenceType.Removed => SupportedType.Removed,
                _ => SupportedType.Unsupported
            };
     }
    

    and then in your method just use the SupportedType enum:

    public void DoSomething(SupportedType difference)
    {
        if(difference == SupportedType.Added)
        {
            // do something
        }
         if(difference == SupportedType.Removed)
        {
            // do something else
        }
    }
    

    Note that you might want to remove the Unsupported member and replace it with throwing an exception, but that really depends on your actual use-case.

    If you expect others to call this method with inappropriate values, you should probably not use an exception but simply perform no action - because exceptions should be used for exceptional situations, but then again, that really does depend on your use case.