0

I'm trying to implement Curiously recurring template pattern(CRTP) in c#.

here is some code i wrote.

using System;
using System.Collections;
using System.Collections.Generic;


// Curiously recurring template pattern in c#
namespace MyApp
{
    public class Program 
    {
        public static void Main (string[] arg)
        {
            new Child().CallChildMethod();        
        }
    } 

    public abstract class Base <T> where T: Base<T>, new ()
    {
        // Game loop
        void Upate ()
        { 
            Method ();
        }

        public void CallChildMethod ()
        {
            T t = (T)this;
            t?.Method ();
        }

        public void Method () 
        {
            Console.WriteLine ("Base Method!");
        }
    }
    
    public class Child: Base <Child> 
    {
        public new void Method ()
        {
            Console.WriteLine ("Child Method!");
        }
    }
}

In output i'm getting

Base Method!

but my code should print

Child Method!

any idea?

Expected

I want to access child class object in base class instead of overriding base methods and please suggest is there any other way to do the same?.

  • See the combined 2 answers above that should answer your question as to why this occurs. – Igor Jan 12 '23 at 15:18
  • Also why not just use polymorphism with `virtual`/`override`? `new` is kind of a code smell I would say. – Guru Stron Jan 12 '23 at 15:20
  • @GuruStron i you're overriding a function in a update it takes cost! – Zain_Ul_Din Jan 12 '23 at 15:21
  • 1
    I highly doubt that it is relevant in 99.(9)% of scenarios. I highly doubt that it is relevant in yours and the cost of CRTP will be less. – Guru Stron Jan 12 '23 at 15:23
  • @GuruStron do you know how to implement this in c#? – Zain_Ul_Din Jan 12 '23 at 15:24
  • @CoderCoder can you please show the actual example when and how you need to implement something like this? What is rationale behind this? – Guru Stron Jan 12 '23 at 15:28
  • I can't verify that `new` vs. `virtual/override` is more efficient but for arguments sake let's say it is. The increase in efficiency is so minimal and insignificant it is not worth the trouble when compared to the complexity and obscurity you are adding to the code by doing it this way. *If* performance is paramount to the degree this does matter then maybe you are using the wrong platform for the job. Chances are though there are other operations in the code that could benefit from optimization that would have a greater impact compared to doing this. – Igor Jan 12 '23 at 15:28
  • Looking at the behavior desired and the inheritance structure you have the way to go about achieving the output is by marking the parent method as `virtual` and the child method with `override`. – Igor Jan 12 '23 at 15:30
  • @Igor let suppose Base.Method is calls in update – Zain_Ul_Din Jan 12 '23 at 15:32
  • @CoderCoder _"let suppose Base.Method is calls in update"_ - and? – Guru Stron Jan 12 '23 at 15:42
  • @GuruStron then method will be overrides on every frame in child class and you can also see updated answer – Zain_Ul_Din Jan 12 '23 at 15:43
  • @CoderCoder _" then method will be overrides on every frame in child class"_ - and? =) – Guru Stron Jan 12 '23 at 15:45
  • and it will take perfomance cost :-) that's the problem – Zain_Ul_Din Jan 12 '23 at 15:47
  • @CoderCoder If virtual method dispatch is too costly for you then I doubt that C# is right language for you. Also you should measure first if this is actual bottleneck in your app (I highly doubt it). If you want to go away from the virtual method dispatch you can try to look into generic + value types +interfaces (generic method/type will be recompiled for every value type). But it is rarely needed. – Guru Stron Jan 12 '23 at 15:49
  • @CoderCoder running managed language takes performance cost (and sometimes quite a huge one). Can you prove that virtual method dispatch cost is actual problem for your app? Have you profiled it? – Guru Stron Jan 12 '23 at 15:50
  • @GuruStron check this [article](https://www.codeproject.com/Articles/266333/Virtual-Methods-Can-Cause-Performance-Overheads) – Zain_Ul_Din Jan 12 '23 at 15:50
  • @CoderCoder that is an article written by someone who knows nothing about proper benchmarking. If you reorder statements then it can give you completely other results proving that virtual dispatch is faster. – Guru Stron Jan 12 '23 at 15:54
  • @GuruStron so what is conclusion? – Zain_Ul_Din Jan 12 '23 at 15:56
  • @GuruStron can i use `delegate` to cache function in a variable and then call it in update? – Zain_Ul_Din Jan 12 '23 at 15:59
  • 1
    @CoderCoder avoid [premature optimization](https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil), profile, find bottlenecks in your actual app, benchmark using right tools against your concrete infrastructure and if needed [race your horses](https://ericlippert.com/2012/12/17/performance-rant/). – Guru Stron Jan 12 '23 at 16:01

0 Answers0