Home > Software design >  Can a public and private non-overloaded constructors exist?
Can a public and private non-overloaded constructors exist?

Time:01-25

Any way to have a private constructor coexist with the public one with the same signature? I've included bare bones code.

struct Wouble
{
    private double value;

    public Wouble(double value)
    {
        this.value = ExpensiveValidation(value);
    }

    private Wouble(double value)
    {
        this.value = value;
    }

    public static implicit operator Wouble(double value)
    {
        return new Wouble(value);
    }

    public static Wouble operator  (Wouble a, Wouble b)
    {
        // Would like this to call the private constructor without ExpensiveValidation
        new Wouble(a.value   b.value);
    }
}
...
Wouble a = new Wouble(5.2);
Wouble b = new Wouble(8.1);
Wouble c = a   b;   // Calls overloaded operator  , I don't want to validate again

The only workaround I could think of is to add a dummy unused parameter to the private constructor to force an overload like this:

private Wouble(double value, int dontValidate)
{ this.value = value; }

and pass a extra ,0 into all internal calls. I also want it to be performant, no unnecessary helper methods etc.

CodePudding user response:

You can try using constructor without parameters (note, that struct always has it):

struct Wouble 
{
    private double value;

    public Wouble(double value)
    {
        this.value = ExpensiveValidation(value);
    }

    public static implicit operator Wouble(double value)
    {
        // ExpensiveValidation will be performed
        return new Wouble(value);
    }

    public static Wouble operator  (Wouble a, Wouble b)
    {
        // No validation here
        return new Wouble() 
        {
            value = a.value   b.value
        };
    }
} 

Then

// Expensive validation will be performed
Wouble a = new Wouble(5.2);
// Expensive validation will be performed
Wouble b = new Wouble(8.1);
// No expenisive validation, 5.2   8.1 = 13.3 is assigned to value  
Wouble c = a   b;

CodePudding user response:

While @Dmitry gave you an answer (a good one), it is worth noting that you are, perhaps, mixing concerns (performance) with overloading (about functionality/behavior), and this can lead to all kinds of issues.

The two concepts are orthogonal (unrelated) so trying to conflate them is counterproductive. I would suggest conveying intent through some other mechanism. Maybe introduce a factory class that does the validation, and leave "normal" initialization to the constructor.

Constructors, generally, should avoid excessive computation.

Going back to the original question, we know now that the short answer is "no, you cannot have the same constructor only vary by access modifier". Overloading is based on the signature of the method by parameter count and type. Return type (if it was a method and not a constructor, and access modifiers are not part of overload resolution).

  • Related