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.
Related
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.
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++.
class Poly
{
public static void WriteVal(int i) { System.Console.Write("{0}\n", i); }
public static void WriteVal(string s) { System.Console.Write("{0}\n", s); }
}
class GenWriter<T>
{
public static void Write(T x) { Poly.WriteVal(x); }
}
Why the innocent (for C++ programmer) method Write is not acceptable in C#?
You can see that the compiler tries to match the parameter type T to concrete overloads before instantiation:
Error 3 The best overloaded method match for 'TestGenericPolyMorph.Poly.WriteVal(int)' has some invalid arguments
Of course. the purpose was not to use the static method as above, the intention is to create a wrapper with polymorphic behavior.
Note: I use VS 2010.
Please, note that all the needed information is available in compile time. Once again: the problem is that the validation is performed before the template instantiation.
Addition after the discussion:
Well, may be I have not stressed this out properly.
The question was not only about the difference between generics and templates, but also about solution of the following problem: given set of overloads addressing different types, I want to generate set of wrapper classes providing virtual method (polymorphism) for these types.
The price of resolution of virtual methods in run-time is minimal and does not hit performance. This is where C++ templates were handy. Obviously, the overhead of the run-time type resolution for dynamic is quite different.
So, the question is whether one can convert existing overloads to polymorphism without replication of the code and without paying the performance penalty (e.g., I am not sure what I gain with dynamic compared to "switch" attempting to cast except of nicer syntax).
One of the solutions I have seen so far was to generate/emit code (sic!), i.e. instead of cut-and-paste to do this automatically.
So, instead of the C++ template processing we simply do it manually or just re-invent macro/template processor.
Anything better?
Short answer:
C# generics are not C++ templates; despite their similar syntax they are quite different. Templates are built at compile time, once per instantiation, and the templatized code must be correct for only the template arguments actually provided. Templates do tasks like overload resolution and type analysis once per instantiation; they are basically a smart "search and replace" mechanism on source code text.
C# generics are truly generic types; they must be correct for any possible type argument. The generic code is analyzed once, overload resolution is done once, and so on.
Long answer: This is a duplicate of
What are the differences between Generics in C# and Java... and Templates in C++?
See the long answers there for details.
See also my article on the subject:
http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx
Why can't you simply write:
public static void Write<T>(T x) { System.Console.Write("{0}\n", x); }
The C++ and C# generics are different ( http://msdn.microsoft.com/en-us/library/c6cyy67b(v=VS.80).aspx , search for "c# c++ generics difference" on your favorite search site)
Short: C# compiler must create complete GenWriter<T> class with all type matching by just looking at the class itself. So it does not know if T will only be int/string or any other type.
C++ compiler creates actual class by looking at instantiation of the generic GenWriter<int> and declaration GenWriter<T> and then creates class for that particular instance.
If someone was to call GenWriter(5.0), this would be inferred to GenWriter<double>(5.0), and the method call inside Write(T x) would become:
public static void Write(double x) { Poly.WriteVal(x); }
There is no overload of WriteVal which takes a double. The compiler is informing you that there are no valid overloads of WriteVal.
C# generics and C++ templates are not entirely equivalent.
You can't do that in C# because the compiler doesn't know what is the type of x in compile time.
Without knowledge of T's actual type, the compiler is concerned that you might have intended to perform a custom conversion. The simplest solution is to use the as operator, which is unamibigous because it cannot perform a custom conversion.
A more gereral solution is to cast to object first. This is helpfull because of boxing unboxing issues:
return (int)(object) x;
Have in mind that C# Generics are not like C++ templates. C++ templates are pieces of code that compile for each type separately. While C# generics are compiled in an assebmly.
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.
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?