5

I wrote this valid piece code, which made me wonder if there was a name for it:

public class GenericObject<T> {
    public T Obj { get; set; }
}
public class DerivedClass: GenericObject<DerivedClass> { }

This leads to the capability of:

var x = new DerivedClass();
x.Obj = x;
x.Obj.Obj = x;
x.Obj.Obj.Obj = x;
// ...
x.Obj.Obj.Obj.Obj.Obj.Obj.Obj.Obj.Obj.Obj...Obj = x;

Which is sure to raise a lot of eyebrows depending on the use case.


Is there a name for this? If so, what is it called, and what is a practical application?

5
  • 7
    I took the freedom to remove any distracting, judgmental phrases from this question to make it appear more professional and less biased.
    – Doc Brown
    Jan 5, 2021 at 8:47
  • 4
    I think the generic aspect of it makes it a bit hard to see that this is just a recursive data structure. I.e. with these particular type parameters, this is the same as class C { public C Obj; }. Note that you can't do x.Obj.Obj = x; without first doing x.Obj = x;, as you'll get a NullReferenceException. Jan 5, 2021 at 9:14
  • 9
    Its called a LinkedList....
    – Polygnome
    Jan 5, 2021 at 10:09
  • 2
    I called it "incest generics" after devising it for Fluent API with inheritance, because I also used constraints that generic parameter to parent has to be its child.
    – PTwr
    Jan 5, 2021 at 11:06
  • @FilipMilovanović is right, this has nothing to do with generics, as you can get the same structure without generics at all.
    – SJuan76
    Jan 5, 2021 at 12:02

2 Answers 2

12

Is there a name for this?

Ok, I may be misunderstanding your scenario, but I think what you're describing is generally called the "Curiously Recurring Template Pattern", CRTP for short.

It deserves mention and being named, but I don't think it is that odd, though; merely a common pattern that is not necessarily immediately obvious.

See:

Generally, whenever you need the derived class information in the base class, you are probably looking for CRTP.

Bottom line: this pattern supports customization of the base class inheritance towards (for the purposes of) the derived class.

7
  • 3
    CRTP is about inheritance, but, I think, OP's pattern in the question is about having properties of the same type as class itself.
    – Fabio
    Jan 5, 2021 at 3:34
  • I don't think you can achieve most of the interesting things you can with CRTP (C++ templates) using C# generics, though, because generics work differently. E.g., you can't do a type-cast in the base class to call a method of the derived class. Jan 5, 2021 at 11:33
  • I also call it CRTP. And yeah the generics work differently from templates, but the nice thing is that they're a reasonably nice approximation for a This-type, instead of having to return a non-specific base class from methods.
    – Kroltan
    Jan 5, 2021 at 12:09
  • 1
    @Fabio: "CRTP is about inheritance" OP's discussed feature (i.e. the infinitely nesting property) stems from them using inheritance (i.e. DerivedClass: GenericObject<DerivedClass>).
    – Flater
    Jan 6, 2021 at 10:47
  • @Flater, OP's discussed feature (i.e. the infinitely nesting property) stems from them using publicly accessible property of the type itself. CRTP is about being able to access derived type from "inside" of base class. One of the good examples described in this answer's links is being able to return derived type from the base class method.
    – Fabio
    Jan 6, 2021 at 16:41
4

Not sure about the "official" name for such "pattern", but it can be used to "model" a hierarchy.

public class HierarchyItem<T>
{
    public T Parent { get; set; }
}

public class Person : HierarchyItem<Person>
{
    
}

Notice that this approach has a risk to create circular dependency.

To avoid possible circular dependencies design types based on the usage (do not try to describe "real life" with single object), instead has different types for different behaviours.

public class Relation<T>
{
    public T Parent { get; set; }
    public T Child { get; set; }
}    
3
  • Can you please expand on this answer? I love the fact that you demonstrate hierarchy with this, and it makes sense to use myPerson.Parent.Parent.Parent.Parent, and definitely concur on the circular dependency issue. However, it doesn't really fully answer my question. +50 for a practical application once the site allows me though! Jan 5, 2021 at 2:12
  • @Tacoタコス, if question is "How to name" such structure - I am not sure. For example if you agree that class properties are just syntax sugar for methods, then String class has kinda similar design "my text".ToString().ToString().ToString().ToString().ToString() ;)
    – Fabio
    Jan 5, 2021 at 2:19
  • The primary question is really if there was already a name. I can adjust my post to make that clear. The secondary question which you have done a fantastic job of answering is a practical application for the pattern. Jan 5, 2021 at 2:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.