Reading a book: NHibernate 3: Beginners guide I found a fragment that made me curious:
Time for action – Creating a base entity
(...)
- Add a new class to the folder Domain of the project and call it Entity. Make the class abstract and generic in T. Your code should look similar to the following code snippet:
using System;
namespace OrderingSystem.Domain
{
public abstract class Entity<T> where T : Entity<T>
{ }
}
My question is: what is the point of the fragment where T : Entity<T>
?
I understand that the where
section can be applied to add constraints on the type T
, but the code above looks like it would be never possible to instantiate such class (if it weren't abstract anyway).
This is most likely meant to provide additional type safety for methods which return (or take in) an instance of the more derived type, saving the callers from having to cast the result to the more derived type.
abstract class Cloneable<T> where T : Cloneable<T>
{
public abstract T Clone();
}
sealed class MyCloneable : Cloneable<MyCloneable>
{
public override MyCloneable Clone()
{
return new MyCloneable();
}
}
MyCloneable instance = new MyCloneable();
MyCloneable clone = instance.Clone();
EDIT
As per @siride's comment, this is known as the curiously recurring template pattern. Eric Lippert has written a great article on its application in C#:
https://blogs.msdn.microsoft.com/ericlippert/2011/02/03/curiouser-and-curiouser/
P.S. And just to illustrate what the above example would look like if you were to take away the generic constraint:
abstract class Cloneable
{
public abstract Cloneable Clone();
}
sealed class MyCloneable : Cloneable
{
public override Cloneable Clone()
{
return new MyCloneable();
}
}
MyCloneable instance = new MyCloneable();
MyCloneable clone = (MyCloneable)instance.Clone(); // Note the cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With