BrandGhost

Power That No C# Dev Should Have - The Dark Side of Reflection

Reflection is a powerful tool that we have access to in C#. And you know what they say: with great power comes great responsibility. And that couldn't be more true with reflection. In this video, we'll check out the dark side of reflection in C#. We'll see how we can break all of the rules and do some... Unspeakable things.
View Transcript
if you've heard of reflection in C then you've heard that there's probably a lot of misuse of how we can leverage reflection my name is Nick centino and I'm a principle software engineering manager at Microsoft in this video I want to show you just how powerful reflection can be this is going to be a beginner video so if you're very experienced with reflection and C this might be a little bit too simple for you but if you'd like a little bit of a refresher or you're very new to reflection and you want to see just how powerful it is this will be perfect for you a quick reminder to check that pin com for a link to my free Weekly Newsletter and my courses on dome train with that said let's jump over to visual studio so we are able to use reflection to easily go get information about a class now reflection allows us to break some rules that we have with compile time code and what we're able to do is basically bypass access modifiers and access modifiers are something we put in place to help guide how people are supposed to use our types and that means if we had something marked as public we're trying to indicate that people on the outside of our class should be able to work with this and if something's marked as private we're saying hey look no one else outside of here should be able to touch this with reflection we get to say who cares we're the boss here so let's go see how that works with this class that I've defined here I've marked the class itself public but everything else inside of it is going to be private so starting with the Constructor I've made this a private Constructor and that should mean that no one can make this by default so marking it private it means no one can say new my class and get an instance of it so we can't really go much further but just to prove what we're able to do I've added in a couple of private Fields as well so these are instance Fields marked as private I've left a comment saying no one should be able to see these except this current class that we're inside of they're marked as private no one can touch this now the other thing that I've gone ahead and done is added in a private method here and again the only spot that we should be able to call this is from right in inside of this class there is no inheriting class there's no other code running this because no one can see it and just to show you on line 59 I can't even add this line of code it won't even compile so that means that if I have this code written here all because I have this private Constructor I can't even make an instance of it and that means that I can't even see this even if I wanted to because it's marked as private sure but I can't even get that far and just to you know kind of illustrate it if I do intellisense here and we get the completion menu coming up it doesn't have my method because it's private so we can't even make an instance we can't even see this private method let's go see how reflection can break all of the rules for us and a quick disclaimer before I do that is that I'm not encouraging you to write code like this seriously this is the reason why people say reflection gets misused you can do some really powerful stuff with it and because you can do powerful stuff does not mean that that you should more often than not when people find out what they can do with reflection they try to use it on everything and there's a reason that we have the typing system that we do in C and there's a reason that we don't use reflection for everything in C in the first place so that's my disclaimer I'll teach you how this works but I don't want you to go apply it to everything you got to promise me that okay let's head back over the first thing that we're going to do and I've shown this in another video is get the constructors that we have access to so using reflection we can get the type that we want to work with which is called my class you can see that on line three up here we're going to get the type then we're going to ask for the constructors which is on line six with the constructors what we'll be able to do is go create an instance of this type and before I go create that instance I just want to print out some information about the Constructor so we can see what we're working with so let's go run this quickly and see what the output is uh-oh wait a second we get the type getting printed out my class but it says that there's no Constructors wait a second didn't I just say that reflection was going to help us break all these rules and now we're being foiled by that private Constructor it's totally hidden from us well yes by default but we have some other things we can use in reflection that give us access to this okay so back in the code here on line 7 through 9 I've changed this up a little bit I've left the original one in on line six so you can still see it but I'm adding in these binding flags and I have nonpublic and instance these are enum Flags I have another video on that by the way which you can watch right up here and that will explain how these flags work with enums and C and what we're able to do is ask for non-public and instance Constructors so let's go ahead and run this now and see what we get and behold we get one Constructor that comes back so we now have access to this private Constructor and no one was supposed to be able to see this on the outside and now that we have the instance of that Constructor let's go create an instance of the type from that Constructor what I'm going to do and this isn't really a safe thing to do unless you know what you're working with we just saw that one comes back so I can ask for the first position within this array but I'm going to invoke The Constructor and null means that I'm not passing in any arguments into that Constructor it's a Constructor with no parameters so doing this is going to basically call the first and only Constructor that we have in that list with no parameters and when we do that we should get an instance of our type back but it comes back as an object so we need to cast it to the type that we want to work with so let's go ahead and run this and see what we get all right we're getting a little bit further right so we have our single Constructor and then we print out to the console that we're about to make an instance and then we get an instance of it so when we pass in instance here on line 23 into the string interpolation we get my Class like that's the two string method getting called on our instance so we do in fact have an instance at this point so so far we've already overcome that first obstacle and I couldn't even get that code to compile earlier when I tried to show you I can't write new my class because that Constructor is private that meant that I could never instantiate it but I've just shown you with reflection that we can go make a new instance of it let's keep going and see how far we can get okay so if we're able to get the constructors and create an instance we should in theory be able to go get the method right we should be able to list all the private methods if we use the same technique with these binding Flags so let's go and see if we can do that all right when I ask for the non-public instance methods we get three methods coming back we can see we have my method which is the one that I defined so this is the one we're truly interested in but we do have a couple of other methods that are not the ones we're interested in but nevertheless these are non-public instance methods that are available on the type so what we should do is try to call this one directly because that's the one that we're interested in what's cool about this is we have proof that we can see it already and just like the Constructor the first step is can we see it and if we can see it the next step is what can we call it let's try it out all right all right so on the screen now I have some link code that's just essentially going to be looking for that single method that we have so this was a collection of three methods I'm just going to look for the one that's called My Method it was also at position zero but I'm not exactly sure if the ordering is always consistent not really sure what the default ordering is I wasn't paying attention if it was the order it was declared in or like alpha numeric or something so I'm just going to ask for it by the name and then what I'm going to do is print out whether or not we have that method and then what I'm going to do is I'm going to call that method so invoke is how we call things but you'll notice what's interesting about this one compared to some of the other things so far is that I have to pass in the instance right when we called the Constructor we don't have an instance yet right we're creating the instance but now that we have one because this is not a static method we need to give it an instance that we want this method to be operating on the null part is because there's no parameters that go into this method but instance is required because this is a nonstatic method or an instance method so we do need to provide that let's go run this and see what we get and I hope you're seeing the power of reflection so far right because we were able to make the instance and now we have access to it we can see that we have a void My Method we have an instance of the method that we can work with and then what I did was I called it this is the console right line from within that method it prints out this is Super T secret and then it prints our two Fields how cool is that we went from being able to not even create an instance of this type to creating an instance and then calling the method we couldn't even do the first step in the beginning but we can go one step further even Beyond this because what we're doing here is printing out the string a numeric value these are two Fields but these are kind of boring right like we have an empty or a null string here we have a zero for the integer I want some different values there but these are private Fields how the heck could we possibly have access to these right well the answer of course is going to be reflection so here's the last part that we're going to work with here I'm going to ask for the fields in the same way that I ask for the methods and the constructors and that means non-public and instance I'm going to print out how many fields we have and then what I'm going to do is try to make sure we can look up the fields by their name this is just like I did with the method so I want to look them up by name I'm going to find the numeric one and I'm going to find the string one but you'll notice that I'm going to call set value on both of these and very much like the method call I need to pass in the instance because we're going to be modifying this particular instance but I also have to pass in parameters because this is the value that I want to set so I am going to be setting the numeric value to 1 2 3 and I'm going to set the string value to ABC and just to prove that all of this works what I'm going to do is I'm going to call that secret method one more time and we'll see what value vales it puts out for us okay let's jump to the very bottom part of this where we get the private fields we find that we have two private Fields exactly as we might expect so we're going to be setting the private fields and then I didn't print out the output of trying to read those values back or anything like that but we call that private method again and if we look at the last three lines of this output the string value has ABC and the numeric value has 1 2 3 and that my friends is how you can leverage reflection to to do some pretty powerful things in C we just broke a ton of rules that we probably shouldn't have to do in most cases the reality is when you're programming long enough with enough edge cases there's probably something like this that will come up at some point however like my disclaimer earlier in the video this is not something I recommend you jump into doing just because you can doesn't mean you should and I'll go one step further and say just because you can with this you probably shouldn't so please please try to leverage this only when you really need to put a lot of thought into this if you find that you're trying to write some code that needs to do this because I would say more often than not you're probably in a situation where something can be designed in a better way so aside from just trying to break some rules using reflection and trying to be cool and show other people that you don't give a crap about their access modifiers why might you want to use reflection well if you check out this video next I'll give you a brief example thanks and I'll see you next time

Frequently Asked Questions

What is reflection in C# and why is it considered powerful?

Reflection in C# allows us to inspect and interact with types, methods, and properties at runtime, even if they are marked as private. This means we can bypass access modifiers and manipulate classes in ways that are typically restricted, which showcases its power.

Is it safe to use reflection in my code?

While reflection can be incredibly powerful, I must emphasize that it should be used cautiously. Just because you can access private members doesn't mean you should. Often, there are better design patterns or solutions that avoid the need for reflection.

When should I consider using reflection in my projects?

You might consider using reflection when you encounter a situation that genuinely requires dynamic type inspection or manipulation that cannot be achieved through standard coding practices. However, always weigh the need against the potential for misuse and complexity.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload