What is Reflection. Why is it useful?

Asked

Viewed 11,641 times

79

  1. It is recommended to use in projects?
  2. How to use?
  3. In what situations Reflection can be used?

2 answers

70

Reflection is a term used to indicate the ability to obtain metadata on the compiled program itself, in Portuguese it can be referred to as reflection even.

As well as metadata?

Getting information about data types, in a dynamic way, is very important for codes that act on objects that are not known at design time. It is widely used in libraries that propose to deal with objects of types that they are unaware of in their conception.

ASP.NET MVC, for example, is only a possible project because of reflection. How could he call the controller methods, which he doesn’t even know?

Seen, it must be said that reflection is not always fast, it is necessary to check permissions, the level of security in which the code is running, among others. Therefore, when one gets any result coming through the reflection, usually this information is cached, ie saved in memory.

It is recommended?

Depends on the use:

  • yes, it is recommended: to create dynamic behaviors using attributes, the only option is reflection

  • yes, it is recommended: to call method that is not known during system design, is also the only option

  • No, it’s abuse to do that: call a method, a class known in design-time using reflection... is absurd

There are so many ways to use reflection that I could continue this list for a long time. So might as well take the following advice: common sense.

How to use?

There are some use vectors of reflection I know. To demonstrate them, let’s first consider the following class:

public class Pessoa
{
    public string Nome { get; set; }
}
  • Lambda expressions: this is a reflection vector, because it is possible to use lambda expressions to get to the types, methods among other reflected objects, that have been used in the expression. It is commonly used to make it strongly typed to obtain reflected objects from members of a class, before that it was only possible to obtain these objects indicating a string with the method name.

    Expression<Func<Pessoa, object>> expr = p => p.Nome;
    var lambda = (LambdaExpression)expr;
    var cast = lambda.Body as UnaryExpression;
    var member = (cast != null ? cast.Operand : lambda.Body) as MemberExpression;
    var propInfo = member.Member as PropertyInfo;
    Console.WriteLine(propInfo.Name); // "Nome"
    
  • typeof(Type): this is one of the most common ways to get reflected information from the system. It serves to get information about the type indicated directly.

    var tipo = typeof(Pessoa);
    Console.WriteLine(tipo.Name); // "Pessoa"
    
  • obj.Gettype(): so common when typeof, but instead of referring to a type directly, it refers to the type of the object in question: but it has a detail, not of the declared type of the variable, but of the object itself.

    var p = new Pessoa();    
    var tipo = p.GetType();
    Console.WriteLine(tipo.IsSealed); // "false"
    
  • Assembly: is used to obtain large-scale types: for example, to scan all existing types in an Assembly, or else in all loaded assemblies.

    // localizando um tipo, dentre todos os tipos carregados
    var todosOsTiposCarregados = AppDomain.CurrentDomain
        .GetAssemblies()
        .SelectMany(a => a.GetTypes())
        .Where(t => t.Name == "Pessoa");
    

And the namespace Reflection.Emit?

It is not clear in my mind whether I consider this reflection or not. But anyway, it’s necessary to use reflection to generate code dynamically, so it has a connection.

As I said, this namespace contains classes used to generate code dynamically... and then compile them. Remember what I said about reflection caching... compiling methods is a good cache target, because after compiled future uses will be very fast.

References:

6


I decided to answer because the answer currently accepts and with many votes is essentially wrong. It’s not that everything is wrong, and I understand the reason for the error, a lot of people get it wrong, until C# has a little confusion in the terminology and helps in the error, but it is a matter of interpretation, C# offers reflection, not only introspection, but most of what is used is not reflection. And the answer is a little outdated. I already explain.

The definition given in the answer speaks of inspection and introspection, not of reflection. Especially the final part denies what is in fact reflection.

I’ll talk about the generic term and take a little bit about C#.

What is Reflection?

Reflection is the ability to modify code, especially at runtime. As per entry from Wikipedia. Do not use the Portuguese version, it is not good for any subject.

Reflection is to treat the code as if it were an application fact.

He is a metaprogramming mechanism. Interestingly I have seen some people dismiss metaprogramming and glorify reflection, which shows that people do not understand well what these concepts are. And then yes, I agree that people should stay away from it, it’s not a simple mechanism.

Reflection and metaprogramming are powerful tools, but they require a good mastery of programming to use well. In some cases only introspection is not so problematic, after all it is read only, the potential of strait is lower.

Yes, this is done because C# has many metadata. At the same time the presence of the mechanism causes a cost of memory to be paid even if it does not use it (in C# it is possible to customize the Runtime not to have, but is not simple task and escapes from the standard).

The compilation time reflection made the term a little outdated, I’ll talk more about.

And I admit that informally people mix introspection with reflection because introspection is part of reflection, but most of the time people are just intruding. And there are controversies where one begins and the other ends]5.

It is recommended to use in projects?

The issue of being recommended is a little complicated and can bump into opinions. I think it is not recommended. Because recommend is talk to use. And it is not to use... until it is necessary. There are cases that is necessary to obtain a result or there are cases that the cost outweighs the benefits.

It generates processing cost and in some cases it is quite heavy, making the application extremely slow. Can you afford this cost? Are you sure you can’t do it any other way?

There are better options even in cases where some reflection is needed.

In what situations Reflection can be used?

Ever thought of using Generics, or direct access with information you already have? It is rare that you can do something useful without knowing how the type is structured, and if you know you do not need this resource. He’s good when you don’t know what’s in there.

If you receive a JSON that does not know the structure and wants to create a type for this data and this requires reflection. Great, good use. But then what will you do with the object created by this type, if the application doesn’t know what it looks like, you can put it on the screen in a generic way, or record it somewhere, probably serialized, which is the form it already had. You realize you can’t do anything specific, so you hardly need to create a class for him?

In some cases it is used to give some productivity. In cases it is only to save typing not worth it. But there are cases that can give more robustness when it gives maintenance and a modification hits other parts of the code.

You have to be careful because if you don’t use this very well the robustness is lost altogether. And in many cases it is only necessary because the design or application architecture is bad. Even in cases that are interesting, there may be better ways.

A better way is the reflective use at compile time that gives more robustness and even more efficiency. The compiler has a lot of information about the code and a good one can give a huge insight capability. And C# has been sensational for this since the creation of .NET Compiler Platform, alias Roslyn.

Although it was always possible, more recently some things have been facilitated to source code generation during the compilation, facilitating reflection (real) at compilation time. And almost all cases of use of reflection should opt for this mechanism and not the classic reflection at runtime.

But it will be difficult to get people used to it, in general it is difficult to teach new tricks to old dogs and on new dogs do not look for the best and most modern materials, take only what is easiest on the internet, ie, what is outdated.

If it does not give or need it all there are other mechanisms a little better than reflection, and C# offers some of them, as already spoken genericity, and dynamism of type as dynamic, that also should be avoided, but not in exchange for the reflection that is worse.

Trying to structure scenarios:

  • Load modules and classes from Assembly and create an instance of them at runtime.
  • Get the fields of an object.
  • In tests, creating fictitious objects during execution startup.
  • To create generic libraries to handle different formats without reprints, sometimes referred to, or using implicit late linking.
  • Build new types at runtime.
  • Examine and instantiate types.
  • Allow changing the value of a field marked as private or protected in a third-party library.

Since they are not ordinary things, it is on account and risk.

Why is it useful?

She can:

  • give more productivity.
  • give greater power and flexibility to codes that need a certain dynamism.
  • replace a hard and dull work, giving more robustness,
  • improves efficiency if done at compile time.

I just hope people don’t abuse this, especially using reflection at runtime.

How to use?

Only I gave several examples, especially in C#, there is a lot on the site about the subject. But almost everything is the reflection of execution, which was prevalent until then, but now the tendency will be to start having more examples using code generation. And a lot of it just uses the introspection part.

The examples of the other answer are just of introspection, it could be different with Reflection.Emit, or more modern techniques using Roslyn to generate code during compilation or even at runtime.

It would not help if I put 2 or 3 examples because it is possible in several ways, follow the link up to see others.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.