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.
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.
Given:
static TDest Gimme<TSource,TDest>(TSource source)
{
return default(TDest);
}
Why can't I do:
string dest = Gimme(5);
without getting the compiler error:
error CS0411: The type arguments for method 'Whatever.Gimme<TSource,TDest>(TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
The 5 can be inferred as int, but there's a restriction where the compiler won't/can't resolve the return type as a string. I've read in several places that this is by design but no real explanation. I read somewhere that this might change in C# 4, but it hasn't.
Anyone know why return types cannot be inferred from generic methods? Is this one of those questions where the answer's so obvious it's staring you in the face? I hope not!
The general principle here is that type information flows only "one way", from the inside to the outside of an expression. The example you give is extremely simple. Suppose we wanted to have type information flow "both ways" when doing type inference on a method R G<A, R>(A a), and consider some of the crazy scenarios that creates:
N(G(5))
Suppose there are ten different overloads of N, each with a different argument type. Should we make ten different inferences for R? If we did, should we somehow pick the "best" one?
double x = b ? G(5) : 123;
What should the return type of G be inferred to be? Int, because the other half of the conditional expression is int? Or double, because ultimately this thing is going to be assigned to double? Now perhaps you begin to see how this goes; if you're going to say that you reason from outside to inside, how far out do you go? There could be many steps along the way. See what happens when we start to combine these:
N(b ? G(5) : 123)
Now what do we do? We have ten overloads of N to choose from. Do we say that R is int? It could be int or any type that int is implicitly convertible to. But of those types, which ones are implicitly convertible to an argument type of N? Do we write ourselves a little prolog program and ask the prolog engine to solve what are all the possible return types that R could be in order to satisfy each of the possible overloads on N, and then somehow pick the best one?
(I'm not kidding; there are languages that essentially do write a little prolog program and then use a logic engine to work out what the types of everything are. F# for example, does way more complex type inference than C# does. Haskell's type system is actually Turing Complete; you can encode arbitrarily complex problems in the type system and ask the compiler to solve them. As we'll see later, the same is true of overload resolution in C# - you cannot encode the Halting Problem in the C# type system like you can in Haskell but you can encode NP-HARD problems into overload resolution problems.) (See below)
This is still a very simple expression. Suppose you had something like
N(N(b ? G(5) * G("hello") : 123));
Now we have to solve this problem multiple times for G, and possibly for N as well, and we have to solve them in combination. We have five overload resolution problems to solve and all of them, to be fair, should be considering both their arguments and their context type. If there are ten possibilities for N then there are potentially a hundred possibilities to consider for N(N(...)) and a thousand for N(N(N(...))) and very quickly you would have us solving problems that easily had billions of possible combinations and made the compiler very slow.
This is why we have the rule that type information only flows one way. It prevents these sorts of chicken and egg problems, where you are trying to both determine the outer type from the inner type, and determine the inner type from the outer type and cause a combinatorial explosion of possibilities.
Notice that type information does flow both ways for lambdas! If you say N(x=>x.Length) then sure enough, we consider all the possible overloads of N that have function or expression types in their arguments and try out all the possible types for x. And sure enough, there are situations in which you can easily make the compiler try out billions of possible combinations to find the unique combination that works. The type inference rules that make it possible to do that for generic methods are exceedingly complex and make even Jon Skeet nervous. This feature makes overload resolution NP-HARD.
Getting type information to flow both ways for lambdas so that generic overload resolution works correctly and efficiently took me about a year. It is such a complex feature that we only wanted to take it on if we absolutely positively would have an amazing return on that investment. Making LINQ work was worth it. But there is no corresponding feature like LINQ that justifies the immense expense of making this work in general.
UPDATE: It turns out that you can encode arbitrarily difficult problems in the C# type system. C# has nominal generic subtyping with generic contravariance, and it has been shown that you can build a Turing Machine out of generic type definitions and force the compiler to execute the machine, possibly going into infinite loops. At the time I wrote this answer the undecidability of such type systems was an open question. See https://stackoverflow.com/a/23968075/88656 for details.
You have to do:
string dest = Gimme<int, string>(5);
You need to specify what your types are in the call to the generic method. How could it know that you wanted a string in the output?
System.String is a bad example because it's a sealed class, but say it wasn't. How could the compiler know that you didn't want one of its subclasses instead if you didn't specify the type in the call?
Take this example:
System.Windows.Forms.Control dest = Gimme(5);
How would the compiler know what control to actually make? You'd need to specify it like so:
System.Windows.Forms.Control dest = Gimme<int, System.Windows.Forms.Button>(5);
Calling Gimme(5) ignoring the return value is a legal statement how would the compiler know which type to return?
I use this technique when I need to do something like that:
static void Gimme<T>(out T myVariable)
{
myVariable = default(T);
}
and use it like this:
Gimme(out int myVariable);
Print(myVariable); //myVariable is already declared and usable.
Note that inline declaration of out variables is available since C# 7.0
This was a design decision I guess. I also find it useful while programming in Java.
Unlike Java, C# seems to evolve towards a functional programming language, and you can get type inference the other way round, so you can have:
var dest = Gimme<int, string>(5);
which will infer the type of dest. I guess mixing this and the java style inference could prove to be fairly difficult to implement.
If a function is supposed to return one of a small number of types, you could have it return a class with defined widening conversions to those types. I don't think it's possible to do that in a generic way, since the widening ctype operator doesn't accept a generic type parameter.
public class ReturnString : IReq<string>
{
}
public class ReturnInt : IReq<int>
{
}
public interface IReq<T>
{
}
public class Handler
{
public T MakeRequest<T>(IReq<T> requestObject)
{
return default(T);
}
}
var handler = new Handler();
string stringResponse = handler.MakeRequest(new ReturnString());
int intResponse = handler.MakeRequest(new ReturnInt());
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.
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.
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.