There is a class Tree , it has a Mass property.

 class Tree { public decimal Mass {get; set;} } 

There is an Apple class inherited from Tree

 class Apple : Tree { } 

Adding to the class Tree an operator overload +

 public static Tree operator +(Tree tree1, Tree tree2) { Tree result = new Tree(); result.Mass = tree1.Mass + tree2.Mass; return result; } 

What type of object will apple3 in the following snippet?

 Apple apple1 = new Apple {Mass = 20}; Apple apple2 = new Apple {Mass = 30}; var apple3 = apple1 + apple2; 

I assume that the type is Tree . And how to make the implementation of the overload remain in the Tree , and as a result get Apple ? The goal is not to write an implementation for each successor Tree .

  • You have actions in operator+ exclusively over the Tree fields, i.e. it is not clear what kind of implementation in the heirs can be speech. - αλεχολυτ
  • one
    @alexolut, 1) the Mass public property will be available to the heirs 2) but there is no point in talking about the implementation in the heirs because question about implementation in ancestor - 4per

1 answer 1

CRTP works well for this situation:

 class Tree<TChild> where TChild : Tree<TChild>, new() { public decimal Mass { get; set; } public static TChild operator +(Tree<TChild> tree1, Tree<TChild> tree2) { var result = new TChild(); result.Mass = tree1.Mass + tree2.Mass; return result; } } class Apple : Tree<Apple> { } static void Main(string[] args) { Apple apple1 = new Apple { Mass = 20 }; Apple apple2 = new Apple { Mass = 30 }; Apple apple3 = apple1 + apple2; // можно присвоить результат сложения в переменную типа Apple } 
  • 2
    Yes, since without limitation you cannot call new TChild in a static method (that is, you cannot create an instance of type TChild without explicit restriction of new ()) - alexoander
  • 2
    When you call new TChild() performance new TChild() is possible. I would not do that. - Pavel Mayorov
  • 2
    @ 3per without any restrictions new() will have to invent another way of generating these TChild - I don’t see a common solution at once. Comrade @PavelMayorov’s remark about performance is true - in such cases, the compiler creates objects of the child class via Activator , that is, not in the fastest way (unless I confuse anything). - ForNeVeR
  • one
    @PavelMayorov, suggest your option, it would be interesting to see. - isnullxbh
  • 2
    If you do not want to create a new object when adding, then you should not make an operator. Then you need a method of the form Tree.Add(Tree tree) . Tree.Add(Tree tree) . In general, operator overloading is extremely rarely needed, and you should not use it without real need. - Astronavigator