1

I have two classes: UNumber and Number (which inherits from UNumber).

Both use the same addition, although Number also looks at the sign of the Numbers.

I want that the addition of Number gets used if one of the objects for the addition method is a Number.

It seems to me that the override Add method of Number gets used if the Add method of an overriding member gets called. (underlying Type Number)

I currently have this code:

UNumber unumber = new();
Number number = new();
number.Add(number);
// Wanted output:   "Add Method of Number"
// Result:          "Add Method of Number"
number.Add(unumber);
// Wanted output:   "Add Method of Number"
// Result:          "Add Method of Number"
unumber.Add(number);
// Wanted output:   "Add Method of Number"
// Result:          "Add Method of UNumber"
// The whole issue lies here. The simple Add Method of UNumber gets called
// instead of the complex Add Method of Number which works fine for UNumbers and Numbers
unumber.Add(unumber);
// Wanted output:   "Add Method of UNumber"
// Result:          "Add Method of UNumber"
UNumber1 unumber2 = number;
number.Add(number);
// Result: "Add Method of Number"

class UNumber
{
    public uint value;
    public UNumber(uint numberin = 0)
    {
        value = numberin;
    }
    public virtual void Add(UNumber numberin)
    {
        value += numberin.value;
        Console.WriteLine("Add Method of UNumber");
    }
}

class Number : UNumber
{
    public bool positive;
    public Number(uint numberin = 0, bool positivein = true)
    {
        value = numberin;
        positive = positivein;
    }
    public override void Add(UNumber numberin)
    {
        // Cannot cast object as this throws an error,
        // I know better workarounds but no neat method to solve this.
        Add(new Number(numberin.value));
    }

    public void Add(Number numberin)
    {
        uint add1 = value;
        uint add2 = numberin.value;
        if (positive != numberin.positive)
        {
            if (value < numberin.value)
            {
                value = numberin.value - value;
            }
            else
            {
                value -= numberin.value;
            }
            positive = !positive;
        }
        else
        {
            value += numberin.value;
        }
        Console.WriteLine("Add Method of Number");
    }
}
New contributor
user31962013 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • 2
    Sounds a bit like an XY-problem. Can you please elaborate why exactly do you want this? Commented 10 hours ago

2 Answers 2

4

Basically that is how polymorphism/overload resolution works and not much can be done about it.

You can try using some workarounds by making UNumber being aware of Number but they arguably lack maintainability and extensibility.

For example via adding an overload:

class UNumber
{   
    public void Add(Number numberin)
    {
        numberin.Add(this);
    }
}

Note that this will obviously fail if you pass Number as UNumber - unumber.Add((UNumber)number) (though in reverse it will call the expected method - ((UNumber)number).Add(unumber) will result in the Number.Add being invoked).

Demo @sharplab.io

Another approach is to type check in the base Add:

class UNumber
{

    public virtual void Add(UNumber numberin)
    {
        if(numberin is Number n)
        {
            n.Add(this); 
        }
        else
        {
           value += numberin.value;
            Console.WriteLine("Add Method of UNumber");
        }
    }
}

Demo @sharplab

Note that both approaches will become a mess when more of UNumber descedants are added.

See also

Sign up to request clarification or add additional context in comments.

1 Comment

Another approach is multiple dispatch... I..e you specify full set of static Add(XxxxNumber left, YyyyNumber right) and call via Add((dynamic)a, b)... Sensible math with open set of types is hard (both to implement, but more importantly to figure out what "sensible" is for unknow future types).
0

Generic will allow the base class to know nothing about descendants:

class UNumber
{
    public uint value;
    public UNumber(uint numberin = 0)
    {
        value = numberin;
    }
    protected virtual void add(UNumber numberin)
    {
        // ...
        Console.WriteLine("Add Method of UNumber");
    }
    public void Add(UNumber numberin) => add(numberin);
    public void Add<T>(T numberin) where T : UNumber => numberin.add(this);
}

class Number : UNumber
{
    public bool positive;
    public Number(uint numberin = 0, bool positivein = true)
    {
        value = numberin;
        positive = positivein;
    }
    protected override void add(UNumber numberin)
    {
        // ...
        Console.WriteLine("Add Method of Number");
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.