Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help to understand this C# generic class

I am learning Nhibernate 3.0. In one of the sample code examples, it creates an abstract base entity class:

public abstract class Entity<T> where T : Entity<T>

then, make the Customer entity inherit from the Entity base class:

public class Customer : Entity<Customer>

I understand it's an abstract generic class, and it is using the where keyword to make sure the type T is Entity<T>, this is where I get confused.

Customer inherits from "Entity<Customer>", this "Entity<Customer>" takes "Customer" as T, but this Customer is not "Entity<T>".

Please help me to understand this, I'm really confused by this generic class.

like image 816
qinking126 Avatar asked Jan 19 '23 03:01

qinking126


2 Answers

You said

customer inherits from "Entity", this "Entity" takes "Customer" as T, but this customer is not "Entity"

That doesn't make any sense because that's what inheritance means. It establishes an "is a" relationship. So in fact a Customer is an Entity

Sorry that was based on the code with the generics stripped out because it wasn't in a code block.

The same principle is still valid though. It's just a little confusing because it looks like it's a recursive definition, but it's not.

Think of it as Customer inherits from Entity There just happens to be methods or fields that depend on the generic parameter being itself e.g. Customer. I'm not familiar with NHibernate so I don't know what the rest of Entity<T> looks like, but I imagine it has some methods that use it's own type as a generic parameter.

Say for instance it has a method called

public IEnumerable<T> GetEntities() 

that returned a list of it's own instances. It needs that method to return the concrete type rather than the base type. So in the Customer class, that method would be

public IEnumerable<Customer> GetEntities<Customer>() 

If it didn't have the generic parameter, it could only return IEnumerable<Entity>

That's just an example of how it could be used, I don't know how it's actually used.

like image 116
Davy8 Avatar answered Jan 29 '23 02:01

Davy8


It will make more sense when you consider what operations the base 'Entity' class tries to perform. I'm also not familiar with nhibernate, but I would imagine one of the methods might be something akin to a Save() method. So any class you create that inherits from the Entity class would inherit a Save() method, keeping you from having to rewrite it for every business object you make. However, the Base entity class has to know what type of object you are trying to save. It could use reflection, but here it uses generics to allow you to tell it what kind of class it is that is inheriting Entity.

The thing is that when 20 different classes inherit from a base class, that base class doesn't really have any knowledge of who is using its functionality. This is a way to let the base class know "Customer" is using its methods so that it can cater specifically to "Customer"'s needs.

like image 28
Brandon Moore Avatar answered Jan 29 '23 02:01

Brandon Moore