This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# vs Java generics
Java use Type erasure while C# keep type information at runtime, what are the practical difference in the behaviors of the language from this design?
There are a lot of issues with type erasure. It brings back bad memories. I haven't used Java since 1.6, so this may be out of date, but some things I remember:
You can't create a new T (or do anything that requires knowing what type T actually is)
Generic lists can't create an array of T
You can't use int, float, etc in generics with Java
This has performance and memory implications because you always have to use the heap versions (Integer, etc)
You can't implement a generic interface with two different Ts, e.g. class c implements IComparable<MyClass>, IComparable<MyOtherClass> is impossible.
More practically, you can't overload methods with different generic types, e.g. by taking in List<T1>, List<T2>, and so on. For example, Java -- How to deal with type erasure in constructors?
Everything is done by casting and boxing
Here's an example of something that's possible only if the type information is kept at runtime:
public string DoSomething<T>()
{
return typeof(T).Name;
}
The closest you could get in Java is something like:
public <T> string DoSomething(Class<T> theClass)
{
return theClass.getName();
}
Something that happens in Java due to type erasure is the creation of synthetic methods called "Bridge methods".
This usually happens when Java tries to compile a class or interface that extends a parameterized class, or implements a parameterized interface. In this case the Java compiler may need to create a synthetic method (bridge method) as part of the type-erasure process, which appears in the stack trace.
The compiler does this to preserve polymorphism of generic types after the type erasure process.
Java's documentation has an example.
Related
The paper Valued Conversions by Kevlin Henney gives a motivation for a so-called variant value type functionality, as well as an outline of a C++ implementation. It is a good read and it covers exactly what I would like to have available in C#: a general type that can hold values of different value-types.
I have not been able to find anything like this in C# though. Somewhat similar questions on SO have unsatisfactory answers and comments like "this is probably not what you want". This surprises me because it looks like fairly commonly required functionality. Henney's C++ boost::any class is widely used.
Is it not possible to create this functionality in C#?
Edit: Responding to one of the answers, I do not think that generics will do the trick. Using a generic requires the developer to know what kind of value-type the Variant variable is holding, and that type becomes immutable for that particular Variant variable as well. But the Variant type I am talking about should be able to hold different types. For example, a function Variant ReadValue() could read an entry from a file, parse it, fill the Variant value accordingly and then return it. The caller does not know in advance what kind of type will be contained in the returned Variant.
This is what generics are for. List<T> where T is anything at all. Generics provide both compile-time and runtime type safety.
You could create your own generic type to store any value you want. You could also cast anything to object and pass it around as such.
You can also use generic constraints to limit your type, such as wanting to only have T be a reference type:
public MyClass<T> where T : class
Or a value type:
public MyClass<T> where T : struct
See more here: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
You can look into using dynamic for this as well.
The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run time.
Type dynamic behaves like type object in most circumstances. However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler.
From what I understand, using any in C++ is same as using combination of object and ChangeType method in C# with exception of having nice syntax for autoconversion from and into the any type. And without limitation just for value types.
Henney's article is quite old (year 2000). In a live lesson (London DevWeek 2008) I remember him explaining low coupling and implementing towards abstractions (interfaces) for the OCP (Open-Closed Principle). He was quite fond of generics and more so generic interfaces. So conceptually it's most probably exactly what he has written about back then, albeit I must admit I didn't read the article. C# generics are even a bit more robust then C++ templates, you should look at Covariance and Contravariance in Generics.
On another note:
What you can't do with generics are variable arity templates, which have been available for C and C++.
This question already has answers here:
What are the differences between Generics in C# and Java... and Templates in C++? [closed]
(13 answers)
C# generics compared to C++ templates [duplicate]
(5 answers)
Closed 9 years ago.
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?
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.
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.
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.
This question already has answers here:
Why must I provide explicitly generic parameter types While the compiler should infer the type?
(3 answers)
Closed 9 years ago.
I've noticed that the C# compiler doesn't infer second generic parameter.
Example:
C++ template code: (yea I know that templates don't work like generics)
class Test {
public:
template <class T,class V>
T test(V v) {
//do something with v
return T();
}
};
int i = 0;
Test t = new Test();
double j = t.test<double>(i); //infers V as int
The templates (and generics) can't infer return type, so in C++ I give it the first template parameter, and the second template parameter is inferred from the variable type.
Now, same example in C#:
class Test {
public T test<T,V>(V v) where T: new() {
//do something with v
return new T();
}
};
int i = 0;
Test t = new Test();
double j = t.test<double>(i); //Error Using the generic method 'Test.test<T,V>(V)' requires '2' type arguments
But if i use 1 type, I don't have to explicitly specify the type:
class Test {
public V test<V>(V v) where V: new() {
return new V();
}
};
int i = 0;
Test t = new Test();
int j = t.test(i); //OK infers V as int.
So, why can't C# generics infer the second type (while in c++ templates it clearly can) ?
I'm sure it's designed that way (I doubt they the .Net team overlooked this), so why is it designed this way that I must explicitly specify both types?
Edit:
From the discussions we had in the answers so far, both languages support overloading by number of template parameters.
So again, why is C# designed this way ? What's different in the language implementation that doesn't allow to explicitly declare only one parameter ?
C# has been designed to be a slightly less brain-bending language than C++.
In particular, I don't think it's a great idea to compare C# generics to C++ templates for various reasons - they're fundamentally two really quite different approaches to accomplishing similar things in some situations. The C++ approach is certainly flexible in some ways - although it doesn't allow (as I understand it) templates which only exist in binary form, or new template specializations to be created at execution time. Basically the C++ templating approach doesn't sit well with the rest of how .NET fits together.
Now as for why you can't specify some type arguments and allow others to be inferred (which is a language decision rather than a platform decision; I'm sure it would be feasible as far as .NET itself is concerned) - again, I believe this is for the sake of simplicity. Choosing the exact right method and the right type arguments is already extremely complicated in C# - more complicated than most C# developers can get their heads round. It involves:
Potentially considering methods up the type hierarchy from the compile-time type of the target
Overloading by number of parameters
Overloading by the number of type parameters
The effect of named arguments
The effect of optional parameters
The effect of generic type parameter constraints on parameter types (not constraints specified by the target method, note)
Method group to delegate conversions
Anonymous function conversions
Type inference for type arguments
Dynamic typing
Generic covariance and contravariance
Personally, I think that's enough to get my head around, without allowing yet more possiblities via "M can still be a candidate if it has at least as many type parameters as specified type arguments". Would you also want named type arguments and optional type parameters? ;)
I've looked at overloading quite a lot, following the spec thoroughly etc. I've found areas which make the language designers scratch their heads and try to work out what the compiler should do. I've found areas which the compiler definitely gets wrong. I wouldn't want to add any more complexity here without a really good reason.
So yes, it's basically for the sake of simplicity, and sometimes that's a pain - but often you can work around it. For every potential feature, you need to consider:
The benefit of the feature to end developers
The cost of the feature to end developers in terms of time spent understanding it
The cost to the language designers in designing and specifying it thoroughly
The cost to the compiler writers in implementing it correctly
The cost to the test team in testing it thoroughly (in conjunction with everything else around overloading)
The cost to future potential features (if this one makes the language more complicated, that leaves less "potentially grokable" additional complexity for other features)
As Dan said, C# doesn't allow you to infer only some type parameters of a generic parameter set. This is likely to enable overloading based on the number of generic parameters (which C# allows, at least for generic classes).
However, you can specify parameters of a generic class, and infer parameters of a generic method within that class. But this workaround isn't always a good solution.
One thing that can help in some cases where one would want to specify some type parameters and have others inferred is to create a generic static class with the parameters one wants to specify, and then within that class have a generic static method with the parameters one wants to have inferred. For example, I have a method which, given a method which is convertable to an Action(T,U,V), along with a T, will generate an Action(U,V) that will call that delegate with the originally-specified T along with the U and V. The method would be invoked as (vb syntax):
NewAction = ActionOf(Of FooType, BarType).NewAction(AddressOf MyFunctionOfBozFooBar, someBoz)
The compiler can determine one of the generic type parameters using the type of someBoz, even though it needs to have the FooType and BarType parameters explicitly specified.
I'm very excited about the dynamic features in C# (C#4 dynamic keyword - why not?), especially because in certain Library parts of my code I use a lot of reflection.
My question is twofold:
1. does "dynamic" replace Generics, as in the case below?
Generics method:
public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {
//test object is not null, regardless of its Type
if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
//do something
}
}
dynamic method(??):
public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {
//test object is not null, regardless of its Type?? but how?
if (ObjToTest != null) {
//do something
}
}
2. does "dynamic" now allow for methods to return Anonymous types, as in the case below?:
public static List<dynamic> ReturnAnonymousType() {
return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
}
cool, cheers
EDIT:
Having thought through my question a little more, and in light of the answers, I see I completely messed up the main generic/dynamic question. They are indeed completely different. So yeah, thanks for all the info.
What about point 2 though?
dynamic might simplify a limited number of reflection scenarios (where you know the member-name up front, but there is no interface) - in particular, it might help with generic operators (although other answers exist) - but other than the generic operators trick, there is little crossover with generics.
Generics allow you to know (at compile time) about the type you are working with - conversely, dynamic doesn't care about the type.
In particular - generics allow you to specify and prove a number of conditions about a type - i.e. it might implement some interface, or have a public parameterless constructor. dynamic doesn't help with either: it doesn't support interfaces, and worse than simply not caring about interfaces, it means that we can't even see explicit interface implementations with dynamic.
Additionally, dynamic is really a special case of object, so boxing comes into play, but with a vengence.
In reality, you should limit your use of dynamic to a few cases:
COM interop
DLR interop
maybe some light duck typing
maybe some generic operators
For all other cases, generics and regular C# are the way to go.
To answer your question. No.
Generics gives you "algorithm reuse" - you write code independent of a data Type. the dynamic keyword doesn't do anything related to this. I define List<T> and then i can use it for List of strings, ints, etc...
Type safety: The whole compile time checking debate. Dynamic variables will not alert you with compile time warnings/errors in case you make a mistake they will just blow up at runtime if the method you attempt to invoke is missing. Static vs Dynamic typing debate
Performance : Generics improves the performance for algorithms/code using Value types by a significant order of magnitude. It prevents the whole boxing-unboxing cycle that cost us pre-Generics. Dynamic doesn't do anything for this too.
What the dynamic keyword would give you is
simpler code (when you are interoperating with Excel lets say..) You don't need to specify the name of the classes or the object model. If you invoke the right methods, the runtime will take care of invoking that method if it exists in the object at that time. The compiler lets you get away even if the method is not defined. However it implies that this will be slower than making a compiler-verified/static-typed method call since the CLR would have to perform checks before making a dynamic var field/method invoke.
The dynamic variable can hold different types of objects at different points of time - You're not bound to a specific family or type of objects.
To answer your first question, generics are resolved compile time, dynamic types at runtime. So there is a definite difference in type safety and speed.
Dynamic classes and Generics are completely different concepts. With generics you define types at compile time. They don't change, they are not dynamic. You just put a "placeholder" to some class or method to make the calling code define the type.
Dynamic methods are defined at runtime. You don't have compile-time type safety there. The dynamic class is similar as if you have object references and call methods by its string names using reflection.
Answer to the second question: You can return anonymous types in C# 3.0. Cast the type to object, return it and use reflection to access it's members. The dynamic keyword is just syntactic sugar for that.
From Wikipedia:
Generic programming is a style of
computer programming in which
algorithms are written in terms of
to-be-specified-later types that are
then instantiated when needed for
specific types provided as parameters
and was pioneered by Ada which
appeared in 1983. This approach
permits writing common functions or
types that differ only in the set of
types on which they operate when used,
thus reducing duplication.
Generics provide the ability to define types that are specified later. You don't have to cast items to a type to use them because they are already typed.
Why does C# and VB have Generics? What benefit do they provide? What benefits do you find using them?
What other languages also have generics?
C# and VB have generics to take advantage of generics support in the underlying CLR (or is the other way around?). They allow you to write code ina statically-typed language that can apply to more than one kind of type without rewriting the code for each type you use them for (the runtime will do that for you) or otherwise using System.Object and casting everywhere (like we had to do with ArrayList).
Did you read the article?
These languages also have generics:
C++ (via templates)
Ada (via templates)
Eiffel
D (via templates)
Haskell
Java
Personally, I think they allows to save a lot of time. I'm still using .NET Framework 1.1 and every time you want a specific collection, you need to create a strongly typed collection by implementing CollectionBase. With Generics, you just need to declare your collection like that List<MyObject> and it's done.
Consider these method signatures:
//Old and busted
public abstract class Enum
{
public static object Parse(Type enumType, string value);
}
//To call it:
MyEnum x = (MyEnum) Enum.Parse(typeof(MyEnum), someString);
//New and groovy
public abstract class Enum
{
public static T Parse<T>(string value);
}
//To call it:
MyEnum x = Enum.Parse<MyEnum>(someString);
Look ma: No runtime type manipulation.
From MSDN:
Generics provide the solution to a
limitation in earlier versions of the
common language runtime and the C#
language in which generalization is
accomplished by casting types to and
from the universal base type Object.
By creating a generic class, you can
create a collection that is type-safe
at compile-time.
Read the rest of that article to see some examples of how Generics can improve the readability and performance of your code.
Probably the most common use for them is having strongly typed ArrayLists. In .NET 1.1, you'd either have to cast everything from object to your desired Type, or use something like CodeSmith to generate a strongly typed ArrayList.
Additionally, they help decrease boxing. Again, in .NET 1.x, if you tried to use an ArrayList with a Value Type, you'd end up boxing and unboxing the objects all over the place. Generics avoid that by letting you define the Type, whether Reference or Value.
There are other handy uses for them too, event handlers, LINQ queries, etc.
Generics in .NET are excellent for object collections. You can define your object type however you want and be able to have, say, a List without writing any code for that, and have access to all the efficient functionality of the .NET List generic collection while being type-safe to T. It's great stuff.
Generics are build on the concept of templates in c++ if you are familiar with them.
Its a way to implement an algorithm or data structure but delaying the actual type it is used on.
List can then be assigned with any type of your choice int, string and even custom types the type is assigned on construction of the list. But you will be able to use the list operations add remove etc.
You can really save a lot of coding effort by getting used to generics. And you don't have to box and unbox between types.
Java have generics as well. They are called wildcards.
Generics in .net, like inheritence and extension methods, allows for reduction of code duplication. Let me explain by way of refactoring.
If all classes with a common ancestor have a common method, place the common method in the classes' common ancestor (inheritence).
If some classes have a common method that uses a public contract to achieve some result, make the common method into an extension method on that public contract.
If some several methods or classes have the same code that differs only by the types acted upon (especially where the details of the type are not relevant to the operation of the method), collect those methods or classes into a generic.
They increase performance for collections using value types, since no boxing/unboxing will be required. They're a lot cleaner to use since you won't have to cast an object (for example using ArrayList) to the desired type - and likewise they help enforce type safety.
Biggest advantage of generics over non generic types in C# (not Java, Java is a different story) is that they are much faster. The JIT generates the best machine code it can come up with for a given type. List<int> is actually a list of ints and not integer objects wrapping an int. This makes generic types awesomely fast and also type safe which can help you detect an awesome lot of errors at compile time :)
The common example is collections. e.g. a set of type T, as an Add(T) method and a T get() method. Same code, different type safe collections.
C++, D, Ada and others have templates, a superset of generics that do it a little different bug get the same end result (and then some).
IIRC Java has generics, but I don't do Java.
The easiest way to explain it is to give an example. Say you want two hashtables, one that maps objects of type string to type int and one that maps objects of type string to type double. You could define Hashtable and then use the K and V types. Without generics, you'd have to use the 'object' type which, in addition to having to be cast to be meaningful, gives up typesafety. Just instantiate Hashtable and Hashtable and you've got your hash tables with proper typechecking and all.
Java also has generics. C++ has templates.
Dynamic languages like Perl and Javascript don't have the same type restrictions so they get mostly the same benefits with less work.
In objective-C you can use protocols to achieve the aims of generics. Since the language is weakly typed however, it's generally not as much of a concern as when you are fighting the type system to use one code path for many types.
Personally I am a huge fan of generics because of all of the code I don't have to write.
What is Inversion of Control?