What is Reflection, why is it useful? How to use?

70
  • Is it recommended to use in projects?
  • In which situations Reflection can it be used?
  • asked by anonymous 15.04.2014 / 23:05

    1 answer

    65

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

    What do you mean, metadata?

    Getting information about data types dynamically is very important for codes that act on objects that are not known at design time. It is widely used in libraries that purport to deal with objects of types that they are unaware of.

    ASP.NET MVC, for example, is only a possible project because of reflection. How could he call the controllers' methods, which he does not even know?

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

    Is it recommended?

    Depends on usage:

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

    • Yes, it is recommended: To call a method that is not known during system design, it is also the only option

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

    How to use?

    There are some reflection vectors that I know of. 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 the types, methods, and other reflected objects that have been used in the expression. It is commonly used to make strongly typed obtaining objects reflected from members of a class, before that it was only possible to get 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: This is one of the most common ways to get system information reflected. Serves to get information about the type indicated directly.

      var tipo = typeof(Pessoa);
      Console.WriteLine(tipo.Name); // "Pessoa"
      
    • obj.GetType (): as common when typeof , but instead of referring to a type directly, it refers to the type of object in question: but has a detail, not is 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 get large-scale types: for example, to scan all types in an assembly, or 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, you need to use reflection to generate code dynamically, so you have 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 compiling the future uses will be very fast.

    References:

    15.04.2014 / 23:16