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.
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.
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 .
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"
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");
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: