Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is this C# construct doing and why? MyClass<TMyClass> : MyClass where

I came across the following code, all in a single file/class. I'm leaving out the details, its the construct I'm interested in. Why are there two different declarations for the same class and how are they different? What's the purpose of the syntax for the second declaration?

public abstract class MyClass
{
    ...
}

public abstract class MyClass<TMyClass> : MyClass
    where TMyClass: MyClass<TMyClass>
{
    ...
}
like image 518
Steve Wash Avatar asked Oct 10 '13 14:10

Steve Wash


People also ask

What is '~' in C programming?

In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...

Why C is used today?

C programming language uses blocks to separate pieces of code performing different tasks. This helps make programming easier and keeps the code clean. Thus, the code is easy to understand even for those who are starting out. C is used in embedded programming, which is used to control micro-controllers.


3 Answers

MyClass - A abstract class named MyClass.

MyClass<TMyClass> : MyClass - A abstract generic class named MyClass<> but with a generic type named TMyClass.

If you rename the types, it will be easier to see:

public abstract class MyBaseClass
{
    ...
}

public abstract class MyClass<T> : MyBaseClass
    where T: MyClass<T>
{
    ...
}
like image 162
Felipe Oriani Avatar answered Oct 13 '22 19:10

Felipe Oriani


Types with different generic arity (i.e. number of generic type parameters, which can be zero or more) are considered as completely unrelated by the language and can have the same name.

This means that you can have classes Foo, Foo<T> and Foo<T,U> at the same time; the syntax will allow the compiler to determine which you are referring to. You can see this happen in the base framework which includes Action, Action<T> etc.

The "recursive" construct class C<T> where T: C<T> (the inheritance from a non-generic C does not change anything so I removed it) is the C# on what is called the Curiously Recurring Template Pattern (CRTP) in C++. Eric Lippert has covered this subject very well in a blog post, where the conclusion is that one should think more than twice before implementing this -- there are problems it can solve, but the solution also has a price.

like image 27
Jon Avatar answered Oct 13 '22 19:10

Jon


public abstract class MyClass<TMyClass> : MyClass
    where TMyClass: MyClass<TMyClass>
{
    ...
}

is a class that inherits from MyClass, and it takes a generic type, which has to inherit from MyClass<TMyClass>


Here's a simpler example of the same thing for you

    public static void Main()
    {
        MyClass<Myclass> other = new MyClass<Myclass>(new Myclass());
        List<int> intlist = new List<int>();
    }

    public class Myclass
    {
        public Myclass()
        {
        }
        public int i { get; set; }
    }

    public class MyClass<T> where T : Myclass
    {
        T value;
        public MyClass(T val)
        {
            value = val;
        }
    }
}
like image 35
Sam I am says Reinstate Monica Avatar answered Oct 13 '22 19:10

Sam I am says Reinstate Monica