Search code examples
c#overloadingoptional-parametersoverload-resolution

Forcing a preference for an overload in class definition?


I have a generic class. It has 2 constructors. Those are widely used in my organization's codebase.

class MyClass<T> {
  MyClass() { ... }
  MyClass(T defaultValue) { ... }
}

I would like to add some functionality but keep backward-compatible. So I would like to introduce a new boolean optional parameter to each constructor:

class MyClass<T> {
  MyClass(bool someFlag = false) { ... }
  MyClass(T defaultValue, bool someFlag = false) { ... }
}

However, I already have a heap of usages out there in which T is boolean and a default value is passed:

class Usage {
  MyClass<bool> Booly = new MyClass<bool>(false);
}

Now, according to the laws of overload preference - the compiler is tying all such constructor usages to the overload accepting someFlag, since typed methods "know better". While making perfect sense in most cases, this is obviously breaking my backward-compatibility.

My question is simple: Is there a language feature available for me to override the default laws of overload preference, and define the old generic overload as the preferred one, so that I don't have to change all such usages?

Of course, a drawback of this design is that whenever I would want to call the first overload (with only the someFlag parameter) - I would have to specify a named parameter as per C# 4 specifications.

Suggestions for other designs are also welcome, but please try to answer my question first :).


Solution

  • Assuming you can have an Initialize() type method that you can call from each constructor, your best bet is to have three constructors:

    MyClass() { Initialize(null, false); }
    MyClass(T default, bool someFlag = false) { Initialize(default, someFlag); }
    MyClass(bool someFlag)
    {
       if (typeof(T) == typeof(bool))  Initialize(someFlag, false);
       else Initialize(null, someFlag);
    }
    
    private Initialize(T default, bool someFlag)
    { 
       // Do whatever
    }