The questions have been answered in the two answers posted so far. I will add something extra that has not yet been said.
In C# the type materialization occurs in Runtime and not at compile time as is the case with C++, for example. In C++ compiler generates a concrete implementation whenever a different type is used.
One of the things that is called for a lot in C++ is that if the code uses many concrete types with a template
you will have a huge code bloat because each concrete type will generate a different code from the template class or method. Java does not suffer from this problem because in the background everything is object
and then there is only one concrete implementation for this type.
Distributed C# code works more or less the same way as Java. Implementation will only take place in memory. It is already a gain, but it would still have a scam of duplicate implementations in memory. Note that the CLR, the virtual machine of . NET, understand the generic code that the compiler issues. JVM does not know how to do this.
But CLR is smarter than this. It creates concrete implementations for each type by value, the calls structs
- that Java does not yet have, and so the primitive types need to be boxed - but for reference types only one instance of this is created to hold any reference. After all, all these concrete implementations need to be created because of the semantic difference of value or reference and because of the size of the data. The reference types all work identically and the size is always the pointer size, so there is no reason to have an implementation instance for each type by reference.
In C++ it is not possible to do the same because the template
is more flexible and each implementation can be different, including having specialized behaviors.
Another point that has been talked about is polymorphism. Some even consider that the genericity allows to dispense with polymorphism if the language is tailored to it. See this:
T Metodo<T>(T obj) where T : TipoPai {
return obj.ChamaAlgo(); //Qual "ChamaAlgo()" será executado?
}
The method ChamaAlgo()
to be called will be that dependent on the type of obj
. And this guy could be TipoPai
or may be TipoFilho1
, TipoFilho2
, TipoNeto
, etc., that is to say any descending type of TipoPai
. Note that ChamarAlgo()
it wouldn’t have to be virtual for this to work in this hypothetical language.
Another aspect that should be discussed is that one of the reasons that wildcards of Java were introduced was to allow co and counter variance of types in the use of it. In C# this is obtained in statement of the kind with in
and out
.
class exemplo<out T> //covariante
class exemplo<in T> //contravariante
I put in the Github for future reference.
That one
public <T> void metodo(T parametro1, List<T> parametro2) {
is from Java... and would aim to do what?– Tafarel Chicotti
@tchicotti For example, do an operation between
parametro1
andparametro2
where it doesn’t matter what their type is, but it matters that they are related (e.g.: insertsparametro1
on the listparametro2
).– mgibsonbr
@tchicotti this happens when you want to declare a generic only at the method level, i.e., the class does not declare generics
– Math
I understood, and it’s possible, I just didn’t answer dpois, because I already had complete answers
– Tafarel Chicotti