Hi,
I have casually looked at one book on C#. With that in mind, I don't believe that there are qualitative differences between Java and C# in that reflection in both is basically limited to introspection. However, I believe Java did it better in that it has class objects that are instances of the metaclass, Class. I may be wrong but I don't believe C#'s Type qualifies as a metaclass. This difference prepares Java to be extended with user defined metaclasses.
Now, let me tell why you want to have user defined metaclasses. Someday, when we all have lots of reflective code, we will want to modularize it. The metaclass allows us to modularize aspects of an application along the lines prescribed by AOP. The advantage is that this kind of modularization is achieved inside the programming language rather than with a new one or with bytecode manipulation.
Of course, the reflective API will need to be beefed up to allow one to modify classes by adding members. Appropriate control of such powerful features will be necessary. For example, adding a field to a class object is safe if the the class has neither instances nor subclasses. Adding a field to a class object that has instances is problematic. In Section 6.4 of "Java Reflection in Action", we present an example of how to structure an application so that a class object can be dynamically replaced when it has instances. This requires a combination of a special class loader and dynamic proxies.