0

I know in C++, generics don't actually exist, but you can simulate it with the use of template. When you build your code, the compiler pre-processes the code and generates a new code with the generic values replaced for the actual values that were specified in the object declaration and then is this new code which is really compiled. For instance, let's say we have the class A as follows:

template<class T>
class A
{
    T f();
};

and then somewhere else in the code we have A<int> a;. The actual code that is compiled would be:

class A
{
    //Replaces T by int in the pre-processing
    int f();
};

After this whole introduction, lets get to the point.

My questions are:

  • Does C# treats generics the same way as C++? If not, how then?
  • Are they special types?
  • Are they resolved in run-time or in compilation-time?
  • How much space is reserved for generic types in the Activation Register?
Peter O.
  • 32,158
  • 14
  • 82
  • 96
educampver
  • 2,967
  • 2
  • 23
  • 34
  • I'm not familiar with the term "Activation Register". I assume it's some kind of official term since you capitalized it. What exactly does it mean in this context? – Cody Gray - on strike Mar 22 '13 at 05:22
  • http://stackoverflow.com/questions/1208153/c-sharp-generics-compared-to-c-templates Have u seen this? – Freelancer Mar 22 '13 at 05:23
  • http://stackoverflow.com/questions/31693/what-are-the-differences-between-generics-in-c-sharp-and-java-and-templates-i – Freelancer Mar 22 '13 at 05:24
  • @CodyGray: What I know as Activation Register is the place in the stack where the memory is reserved for the variables of a specific scope. – educampver Mar 22 '13 at 05:26

3 Answers3

6

This is a very broad topic and can better be explained by:

http://msdn.microsoft.com/en-us/library/c6cyy67b.aspx

To sumarize (from MSDN article linked above):

  • C# generics do not provide the same amount of flexibility as C++ templates. For example, it is not possible to call arithmetic operators in a C# generic class, although it is possible to call user defined operators.

  • C# does not allow non-type template parameters, such as template C {}.

  • C# does not support explicit specialization; that is, a custom implementation of a template for a specific type.

  • C# does not support partial specialization: a custom implementation for a subset of the type arguments.

  • C# does not allow the type parameter to be used as the base class for the generic type.

  • C# does not allow type parameters to have default types.

  • In C#, a generic type parameter cannot itself be a generic, although constructed types can be used as generics. C++ does allow template parameters.

  • C++ allows code that might not be valid for all type parameters in the template, which is then checked for the specific type used as the type parameter. C# requires code in a class to be written in such a way that it will work with any type that satisfies the constraints. For example, in C++ it is possible to write a function that uses the arithmetic operators + and - on objects of the type parameter, which will produce an error at the time of instantiation of the template with a type that does not support these operators. C# disallows this; the only language constructs allowed are those that can be deduced from the constraints.

In general, although they share similar syntax and uses is most cases, there are many large differences in usage and capabilities.

Inisheer
  • 20,376
  • 9
  • 50
  • 82
  • 4
    This is a good answer and a good reference, but [you can make the answer even better](http://meta.stackexchange.com/q/8259) by including a more complete summary of the linked content. That way, when Microsoft inevitably reorganizes the MSDN library and breaks all the links, we'll still be able to find the answer here. – Cody Gray - on strike Mar 22 '13 at 05:23
  • 1
    Another big thing that this doesn't seem to mention is the fact that (C# 4.0) supports covariant and contravariant generics, while C++ templates T and T are completely separate types for any A and B. – Yuushi Mar 22 '13 at 05:57
3

There is a misunderstanding regarding how C++ templates are resolved. In C++, templates are processed two times (note: the term "pre-processed" is reserved to the Preprocessor, which has nothing to do with templates at all).

On the first processing time, non-dependent names are resolved, whereas dependent names are not resolved:

int x;

template <typename T> foo() {
    x;    // <-- resolved in phase 1
    T::x; // resolved in phase 2, depends on "T"
}

Phase 2 is entered upon instantiation. E.g.:

struct Frob {
    int x;
};

int main () {
    foo<Frob>();
} // <-- instantiation happens right before the '}'

Also, C++ templates are instantiated lazily, on a per-function basis. This means that not everything in a class template must be resolvable. Only functions actually used are instantiated, which means phase 2 is only entered for used member functions.

This makes templates more versatile than C# style generics: When you instantiate a class template, the instantiated-upon type only has to support a subset of the template.

In C#, generics are resolved eagerly. The "instantiated-upon" type has to support everything the generic class only potentially uses, which puts rather stringent limits on the versatility.

You know already, but both are really distinct concepts. Generics are a runtime construct, and with reflection and self-modifying code, the C# language has to be very defensive w.r.t. resolvability. Templates are a compile time construct (note: not _preprocessing construct!), supporting Turing-complete meta-programming with both type- and non-type-arguments and a powerful compromise between eager and lazy instantiation.

Both have their features.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
1

The implementation of .NET generics is something of a mix.

When the generic class is compiled into MSIL, it's compiled into a single generic type definition.

When clients use the generic class, the .NET runtime compiles separate copies of the class's machine code for simple type parameters (bool, int, etc.) but separate code isn't generated for different object types; they all share the code for Object.

j__m
  • 9,392
  • 1
  • 32
  • 56