Say we want to define a class that allows basic arithmatic, called 'Addable'. Addable things can be added.
abstract class Addable
{
public abstract Addable Add(Addable X, Addable Y)
}
What is the correct way to implement an Addable? The following doesn't work, it gives:
Number does not implement inherited abstract member Addable.Add(Addable, Addable).
class Number : Addable
{
public int Value;
public Number(int Val)
{
Value = Val;
}
public Number Add(Number X, Number Y)
{
return new Number(X.Value + Y.Value);
}
}
I think the problem is that Add takes (Number,Number) as its arguements which aren't generic enough, but I do not know how to proceed.
Edit: As some people have requested to know what this is to be used for, let me elaborate. I am using an algorithm that relies on taking the maximum of several objects. Depending on the use case, these objects are numbers, or distributions. To stay with the example above I will pretend I need to add these numbers or distributions. So I want to have code that looks something like:
Addable LongAlgorithm(Addable X, Other parameters)
{
... // Lots of code that may contain X
Z = Add(X,Y)
... // Code Using Z.
return Answer // Answer is of the same type as X in the input.
}
Edit 2: With the feedback given this question seems to be drifting into the realm of "Interface vs Base class". Perhaps others who read this question might find that question illuminating.
I hope the question is clear, I am new to S.O. and although I have tried to stick to the guidelines as much as possible, I will be happy to modify the question to make it clearer.
It all depends on why you want that Addable
base class, and how it will be used. It's worth updating your question to explain this. Here's one possibility, which might not meet your use-case:
public interface IAddable<T>
{
T Add(T x, T y);
}
public class Number : IAddable<Number>
{
public int Value { get; set; }
public Number(int value)
{
Value = value;
}
public Number Add(Number other)
{
return new Number(Value + other.Value);
}
}
You could of course use an abstract base class as well here, if there was a need:
public abstract class Addable<T>
{
public abstract T Add(T x, T y);
}
If you want to make sure that types can only do class Foo : IAddable<Foo>
and not class Foo : IAddable<Bar>
, then you can add a generic type restriction:
public interface IAddable<T> where T : IAddable<T>
{
T Add(T x, T y);
}
In response to your edit:
Use my types from above and do this:
T LongAlgorithm<T>(T x, Other parameters) where T : IAddable<T>
{
... // Lots of code that may contain x
T z = x.Add(y);
... // Code Using z
return z;
}
Note that I've changed your Add
method so that it's an instance method, which adds itself to another instance.
If you wanted to keep the signature as Add(x, y)
, you probably want something like this:
public class Number
{
public int Value { get; set; }
public Number(int value)
{
Value = value;
}
}
public interface IAdder<T>
{
T Add(T x, T y);
}
public class NumberAdder : IAdder<Number>
{
public static readonly NumberAdder Instance = new NumberAdder();
private NumberAdder() { }
public Number Add(Number x, Number y)
{
return new Number(x.Value + y.Value);
}
}
T LongAlgorithm<T>(T x, IAdder<T> adder, Other parameters)
{
... // Lots of code that may contain x
T z = adder.Add(x, y);
... // Code Using z
return z;
}
Then call it like
Number z = LongAlgorithm(new Number(3), NumberAdder.Instance, ...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With