So in this video, we're going to talk about topics 16.
What is reflection?
Reflection is a mechanism that allows us to write code that can inspect types used in the application.
For example, using reflection, you can list all fields and their values belonging to a given object,
even if at compile time.
We don't know what this object type is exactly.
This probably sounds a bit mysterious to you, so let's consider the following use case We wanted to
write a class that can take away the objects and save them to a text file.
Of course, they are already mechanisms that do it and still objects.
Ask Jason or Azimo, but let's say we want some custom format, so we must implement it ourselves.
We want this class to be completely generic so it can take any type of object.
And here we have two simple types that this class would convert to text.
For brevity, I define them as records, but we'll learn about later in the course.
If an object is being converted, I would like the result to be something like this.
Similarly, for a house, I would like to have this.
The problem is that in the convert method, we have no idea what type we deal with.
We can't cast the parameter to anything concrete as the type may vary.
Also, to implement what you want, we will not only need the values of the properties which we could
access if we only had more concrete type than system object, but we also need their names, which is
not available at runtime.
In other words, when using House First Property, we can get the number two, but we can't get the
floor string and we will need it to build the string result.
Well, actually, we can get the name of the property, but only if we use reflection.
Reflection allows us to access information about some type at one time.
We can not only access the values of some fields, but also their names.
Moreover, we could access information about methods, constructors, access modifiers and so on.
Let's see this in practice.
First of all, we will use the grid type method on this parameter.
It will return a type object which provides or information about the type.
Let's run this code and see the type object in the debugger.
As you can see, there is quite a lot of data in here.
We have some information about constructor's methods, base type and also properties.
We can see all properties we declared in the house type and also on extra equality contract property,
which is auto generated for records.
Well, ignore it when converting the object to streak.
All right.
Let's use this data to achieve what you want.
First, I want to read all properties from this object, except the quality contract.
This gives me an eye on the morale of property info.
Now I want to build a strength for each property ethos.
Accessing the property name as well as its value and then doing the strings together.
I will use Link to know it.
If you don't know Link, I have a course about that.
See the last section in this course to find out more.
The select committee it comes from Link and it simply maps every property to a string.
I join those things together using this remodelling method.
Let's make sure this method works.
Right.
Seems everything is working.
We're used to perfection to access the information about some type at one time and read the values and
names of its properties.
Reflection gives us much more ability.
Here are some of them.
Loading dials at one time and using types defined in them, instantiating a new instance of some object
of a specific type at runtime.
For example, we can create an object of a type defined in the yellow that we hold, finding all process
derived from a specific type or implementing a specific interface reading the attributes.
This is, for example, what an unitard does when it runs the tests.
It finds Olmer to which the test attributes and executes them.
We'll learn more about attributes in the next lecture.
Running a method by its name, for example, if the user of the application selected it from some dropdown
debugging.
For example, sometimes it is necessary to find out the list of all currently loaded assemblies creating
new types at runtime system reflection image namespace is used for that, and many more.
As you can see, a reflection is a powerful tool, but a search should be used with caution.
The code that heavily relies on reflection is usually hard to maintain and understand.
It's also prone to errors.
For example, when you call a method by its name, but someone changes the name without your knowledge.
The code will crash the next time it's wrong because no method with this name exists anymore.
Also, using reflection has a relatively big impact on performance at one of the projects I worked on.
I was asked to improve the performance of some process.
This application was using réflexion, I wrote, mostly to build some types and attributes from the
others at runtime.
It turned out that the results of those load can be cached, and only this improvement make the process
work twice as fast as before.
We'll learn more about this mechanism in the whole discussion lecture, so use reflection with caution.
If there is a convenient way of implementing the same logic without it, go for it.
If not, reflection, maybe a lifesaver, but keep an eye on the performance.
Let's summarize.
Reflection is a mechanism that allows us to write code that can inspect types used in the application.
For example, call a method with the gnome equal to given string or list or fields and their values
belonging to some object.
The topic of reflection is quite common during the interviews.
If it comes up, there is a big chance you will be asked What are the downsides of using reflection?
Well, it was a relatively big impact on performance.
Also, it sometimes makes the cold hard to understand, and then it may also tempt some programmers
to hack some code, for example, to access private fields at runtime, which may lead to unexpected
results and hard to understand bugs.
All right, that's it for this video.
We'll continue the topic of reflection in the next lecture, where we will talk about attributes.