In the previous question, Inheriting operator overloading , suggested what should be done so that the ancestor could return instances of the heir class.

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 } 

But it was noted that new TChild() is a performance bottleneck. Why? What are the options for optimal performance when generating in the ancestor code instances of the heir?

  • Hm The idea of ​​creating a descendant in the ancestor code seems doubtful to me. (Yes, and CRTP to the heap, too.) - VladD
  • @VladD, is it really better to duplicate code in descendants? True, there is another option with bringing the result to the type of descendant. - 4per
  • Depending on what your real task is. Tell us why you really such a strange structure of classes. For example, maybe you don’t need inheritance at all, since you don’t add data and new constructors appear? - VladD
  • 2
    When I needed to do a similar thing, I did the operations individually. The fact is that not all operations have a physical meaning. For example, to add two points in time is meaningless. And you can add a moment of time and duration, and get a moment of time. You cannot add points, but you can add vectors (and get a vector), as well as a point and a vector (and get a point). And so on - VladD
  • one
    By the way, in F # your task (partially) is solved “out of the box”: blogs.msdn.microsoft.com/andrewkennedy/2008/08/29/… (at least there is a built -in dimension analysis ). - VladD

1 answer 1

The performance is bad because new TChild() turned into a constructor call through reflection.

As a possible alternative, you can make the virtual method protected virtual Tree<TChild> CreateFromMass(decimal mass) , which will construct the object. In a descendant class, you can overload it in order to construct an object of the correct type.

  • tried it. Probably need protected virtual TChild CreateFromMass(decimal mass) - 4per