Advanced C#: 05 Reflection

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to another lesson in the advanced c-sharp course brought to you by Tut's plus now this lesson I'm going to dig into one of the deep and dark corners of the c-sharp language and that is reflection now you can think of reflection very similarly to how you view your own reflection when you wake up in the morning and go into the bathroom and you look at yourself in the mirror you see a reflection you see things that make up yourself the characteristics of yourself your face your eyes your ears your nose your mouth arms and legs and all those things that make you you well reflection within the C sharp language does exactly the same thing it allows your code or your assembly to look within itself and take a look at and inspect those characteristics that make it itself now it's kind of interesting when I first began learning about reflection it's one of those topics where I kind of felt like this is a really cool parlor trick but it doesn't really serve much of a purpose for me and that was the case for awhile but as I started to play around with it more I saw that it was very powerful in fact but like anything else with great power comes great responsibility and that if you misuse it it's definitely going to be to the detriment of the performance of your software so let's go ahead and jump into some code I'm going to show you a little bit about reflection how to use it what it can do for you and one of the nice little sweet spots that allows you to use it to make your code very dynamic so here we are back in visual studio and I'm going to start like I normally do creating a new project a console application and click ok so now here we are within our code within our main method of our class program or better yet our type program within our console application 16 assembly and that's ultimately what's going to be created for us by visual studio and the compiler when we build this it's going to create that dot exe for us and we're not limited to doing reflection within console applications or exe files we could also do them in class libraries in the dot DLL files as well but for this case we're going to run it through this console application to show you what I'm talking about so the first thing you need when you're talking about reflection is you actually need an assembly to reflect upon or to inspect so let's do that first so I'm going to create a new variable and I'm going to call it assembly and now we need to set that to an assembly so the simplest way to do that is to use the assembly class which is found within the system dot reflection namespace so I'm going to add that to my file and then I'll call the method get executing assembly which as you would probably expect gets all the assembly information about the current executing assembly so in our case that's console application 16 so now that I had that what's the most logical thing for me to do first well that would be to write out some data to the console so I can show you that I actually have it so let's do a console.writeline and we'll do assembly dot full name so I'm going to go ahead and do ctrl f5 to run this and you see something rather interesting here you're going to see a very long string with a little bit more information than you probably had bargained for and what this is is the fully qualified name of your assembly which is made up of four parts the name of your assembly which in this case is console application 16 the current version of that assembly which by default is 1 dot 0 dot 0 dot 0 and you can update that within your code if you'd like to but for our case we're just going to leave it that for each version for each build of our application and then the culture and the public key token now these some of these topics are definitely beyond the scope of this lesson but just understand that these four things put together can uniquely identify your assembly and these things are very important once you get into topics like strongly typed assemblies or as somebody's that are loaded into the global assembly cache which is a little bit beyond the scope of this lesson so let's go ahead and dig back into our code and see what other things we can figure out about our assembly so right now we have the name and that's pretty cool but what else can we do well I alluded and started to talk a little bit in the previous lesson about getting the types out of your assembly and what are types at the end of the day they're really just classes so let's jump back into that one again so let's save our types is equal to assembly and there's a lot of really nice helper methods and properties in here and I'll leave some of them for you to kind of play around with yourself because once again that's the best way to learn I'm just going to give you some of the more common that you can work with so in this case I wanted run get types so now I have a collection of types that I can go ahead and loop through in a for each statement and I will say var type in types and I'll just write the name out and I'll do a little bit of formatting here so we can see things a little bit easier then we'll say type dot name so I'll go ahead and run that control f5 so now I'm seeing within my Assembly I'm finding one type which of course makes sense because I only have one class in here called program well program is a little boring so I'm going to beef this assembly up a little bit and I'm going to add in one more class we'll call it public class sample and we'll throw a few things in here just to make it interesting so I'll create a property it'll be a string and we'll call it name and I'll create a field and this one will be an integer we'll call it age and will create one method here just to round things off it'll be a void we'll call it my method no arguments and it's really not going to do anything for now so we'll do a save ctrl f5 and now you're going to see two types found within my assembly which is exactly what I would expect I have two classes which equate to two types program and sample all right well that's not too bad but what can I do with these types now that I have them well you can do an absolute ton so if you just kind of peek into some of the the intellisense here there's an awful lot of helper methods in here once again I'm going to leave a lot of these for you to play around with and they're very self explanatory surprisingly enough for as complicated as the topic of reflection can be but once again I'm going to show you a few of them on here that are very useful when you're getting started and learning about reflection so if you just take a look at our type down here our class I see a property a field and a method so let's see if we can start using reflection digging into our assembly and types to find these things and print them out to the console and we can do just that so first we're going to start with finding our properties and we'll set that equal to type which is the current type that we're looping through and we want to get properties and so now I have a collection of those properties within my variable and I can once again for each through those and I can say for prop in props and I can once again console.writeline prop dot name and will preface this with some formatting as well just to make things a little bit more clear we'll do a tab and we'll say property and concatenate there we go ctrl f5 so now we can see within our sample type within our sample class we have a property called name and if you really wanted to dig in a little bit further you could even tell the console here to write out what the particular type of that property is so you could say property type plus prop dot property type and I have to remember to concatenate this with the plus sign ctrl f5 and as you can see here we have a property whose name is name and the type is system dot string so now what do we have so we have our property in here how about fields while we do that in the exact same way and I hope you're starting to see a trend here because doing this type of thing is very common across all the different characteristics of your code whether its properties fields methods events or whatever you're trying to work with so I can say type that get fields and I can go ahead and for each through those once again field fields and we'll just write the name out to the console field field name ctrl f5 so now we have a field and its name is age alright well that's pretty simple and let's just round it off since I know I have a method in here we'll do the same thing for methods of our methods equal to type and as you can imagine there is a get methods method and we'll once again loop through those method in methods and we'll console.writeline method dot name so there we go now this is a little bit more interesting if you take a look at this what you're seeing here is probably a little bit more than you would have anticipated so if I look down in my sample class I see that I have a my method but I don't see anything else here but what wound up happening is I got a lot more methods that I may have anticipated and this is one of those things where it's kind of interesting especially when it comes to the first two methods at underscore name and set underscore name I created this name property as an automatic property and that's one of those syntactical sugar things that c-sharp does for you that just because you write something in a certain way within c-sharp doesn't mean it has a direct translation into the the MS il code and ultimately what runs within the dotnet framework so one of the things that the compiler does for you when you create an automatic property is to create two methods behind the scenes a get underscore name and a set underscore name to handle the getting and setting of that property so then I see the third one is my method which I would anticipate would be exactly what I thought it would be but then I also get the two string equals get hash code and get type methods but I don't see those where are those coming from well those are coming from the inheritance that is inherently built into all classes within the c-sharp language when you create any class it will by default whether you specify it or not inherit from the object class which is the absolute base of everything and I will show you that here simply by appending a little bit extra to our type here and we'll say base type and I will type type dot base type so if I do that ctrl f5 I'll see now that everything both of my types program both have a base type of system dot object and if I take a look in the object browser that you can get to via view object browser or the keyboard shortcut ctrl W J if I take a look at my console application and I expand this all the way down I see my program I see my sample and I see base types in both of them equating to object and as you can see in here we're seeing equals get hash code get type and to string so very interesting how that works I hope you're starting to see how this reflection concept can be very powerful it allows you to dynamically dig through your own characteristics or your codes own characteristics to do interesting things with them now you do have to understand that every single time you do one of these calls to get fields or get methods or get me the executing assembly you're going to take a slight performance hit because there is some work that the.net framework has to do to look into itself or look inside these assembly files because at the end of the day these things are files and there has to be some reading done in order to get this information but for our purposes this is fairly simple and we're not really worried about performance but it's definitely something that you should keep in mind when you're doing this in your code that's going to be running ultimately in production and probably running your business so yeah this is interesting but what's this going to do for me I can't really do anything with these things it's just telling me that things exist well on the contrary you can actually execute things through reflections so let's take a second to look through that and see what that means so let's say if I drop down a few lines here and I decided that I wanted to create a new instance of my sample class I'll save our sample equal to new sample and I will initialize my property in my field we'll give name is equal to John and age is equal to 25 so now I have an actual instance of my sample class and what could I do to it if I wanted to play around with reflection to get some data out of there not just what these properties or things might be well you start down the same path as you did before in that you need to get this type this is this is the the glue that kind of holds all this reflection stuff together so I need to get a type well there's two ways you can do that both will also altima take you to the same place but in slightly different directions so i can create VAR sample type and i can assign it to type of which is merely just an operator that's going to get the type of a type that you specify within its parameter this is going to give the sample type a type of sample you can also do it via the sample dot get type method both of them will ultimately end in the same way the only difference is that this get type method is more of a runtime operation and that you really don't know where the compiler doesn't really know what you're going to get until you've executed this code whereas the typeof operator if I specify sample is more of a compile time operation where it can tell I know specifically I'm running this type of operator to get a type of sample ultimately it's up to you use either one you want I'll stick with this one for simplicity sake so now I have that type well just like we started to get the methods or get the properties before I'm going to do something very similar so I'm going to get the name property from my sample type but the way that we do that is via the sample type since I have the type now I want to get a property I want to get a specific property not all properties so let's go ahead and do that so now it wants a name and it actually wants the name of the property and in our case that is name now you do have to pay attention because c-sharp is case sensitive because I named this name with an uppercase n that is the way I have to specify it within this parameter if you don't you will get an error you won't get or you won't get an error but this name property will come back is null so you just kind of have to watch what you're doing when you're passing in these strings so now that I have the property I want to get the value so let's do a console.writeline so I can write it out and we'll say property and we will concatenate to that the name property and I want to get its value but when I ask to get its value I need to specify the object for which I want to get the name property value from and in our case that is sample so now that we've done that I can do ctrl f5 to run and as you can see here I found the property and its value is John and you can see that based on the helper methods that are found within that type sample type I can do the same thing for fields I could say get field and ask for a specific one I can get a specific method or members or whatever you want to get so in this case one of the things I want to get a little bit closer to towards the end of this lesson I want to show you about executing methods because this is where some of the very interesting points of reflection come into play so let's back up a step here and I'm going to delete this and I'm going to put a little code in here just to show you that I'm not then I'm not faking this and we're going to console.writeline hello from my I method and we'll close that off we'll save will do control f5 and we don't see that on the screen anywhere so now what we're going to do is within our reflection code I'm going to get that particular method so I want to do VAR my method is equal to just like we did before we're going to go into sample type we're going to say get method and we need to specify the name of the method so we'll say my method and now we have the method stored within our my method variable and now I want to execute it so then to execute this I'm going to specify my method dot invoke and now there are a couple parameters that I need to specify I need to specify the object reference to which I want to execute this method on and in my case it is sample and then I need to specify any parameters that need to go into my method in my case there aren't any so I can simply say no I can save and ctrl f5 and now you can see I have actually executed my method without directly calling it on my sample instance object so I've seen hello from my method so this is kind of where things start to get a little bit interesting and as I alluded to on the previous video when it comes to attributes you can do even more interesting things with reflection when they're coupled with attributes so I'm going to take you through kind of an interesting scenario here one of which I think is very powerful within the concept of reflection and could really help you possibly in the future so let's take a step back and let's go and create a couple attributes here just to build up this example a little bit so if you remember from the previous lesson and attribute is nothing more than a class so I'm going to create a public class we'll call this my class attribute and if you recall it the only thing you have to do in order to make an attribute an attribute is make it inherit from the attribute class in this case I want to narrow this down to only be able to be applied to the class and the way we do that is through the attribute usage attribute and we'll specify the attribute target as a class so now this attribute can only be applied to to a class so let's go ahead and apply the my class attribute to the sample class and I want to create one more that's going to be at the method level so I'll create a my my method attribute and it's going to inherit from attribute with no implementation and once again I want to make sure that my attribute usage is going to restrict this to only be assigned to a method so now I can save this and I will apply this attribute to be my method method so now I can save this I can build and everything runs just fine all right so now let's use that concept of reflection and assemblies to dig a little bit down into these classes these types and methods that are found within here via these attributes so I'm going to get a reference to my assembly once again I'll say assembly dot get executing assembly and now I'm interested in getting types but I'm not just interested in getting all types I only want to get the types that are associated or that have the my class attribute associated with them so let's do this again var types equal to are actually better yet we'll call this my types or sample types all right we'll call it types just for simplicity sake and now I can say assembly dot get types and now that I've done that I want to specify that I want to get the types where get custom attributes and that custom attribute that I'm looking for is the my class attribute so I want to get those where get custom attributes where the count of that is greater than zero which basically at the end of the day simply means that I want to get all the types within my assembly where there are custom attributes assigned to that type and not only any custom attribute but the my class attribute and as long as there's more than one that's being assigned to that type I want to get it back so let's see if I successfully did this is do a console.writeline I have to loop through these first we'll do a for each bar type in types and I want to do a council right line type that name control f5 so there we go we did not get programmed this time like we did last time we only got sample because it has the my class attribute assigned to it so now that I've done that I want to be able to get the method that is associated with the my method attribute and we'll do that in a similar fashion to how we did before so once we're in the type that has the my class attribute now I want to do a VAR methods equal to type dot get methods we're going to do very similar to how we did previously we'll do where and we can specify where our method dot get custom attributes of the my method attribute once again where the count is greater than zero so now I'm going to get all of the methods within the type sample or within the type that has the my class attribute that has the deck that has been decorated by the my method attribute where the count is more than one so that we know that it exists on that particular method so once again we will do a for each var method methods and then we'll do a console right line method dot name so we should only be getting in here obviously the my method and just to make sure that I'm not cheating here I will create another method in here public void no attribute method that's not going to do anything and I'll rerun this and you will still only get my method and you might be saying well you're just doing the same thing as you were before well not not actually so as you can see in here in previous I was just saying give me all the properties or give me all the methods or things like that now I'm assigning attributes to my class and to my methods that allow me to a little bit more generically or declaratively get certain specs of my code so this works out extremely well when you want to write some very flexible some very dynamic code so that you don't have to say I want this particular instance or I want that particular method I want this particular property you can now do things you can decorate things with attributes and allow the reflection to dig in to get those things for you and then execute them so basically this really allows some flexibility some dynamic nature to your code to allow you to be very flexible in adding functionality and being able to dynamically grab certain pieces based on these attributes and execute them whenever you want so this is a very cool trick I use this quite a bit so I would definitely encourage you to play around a little bit more with reflection and then how it plays around with different aspects of your code different characteristics whether it be through attributes or just grabbing those characteristics through specifically looking for certain ones and executing them or just in general playing around that is it is a very cool tool and if nothing else it is a very good parlor trick and it is definitely something that I think you should get familiar with for your usage in development in the future so I hope you found this very interesting and I will see you in the next lesson
Info
Channel: Clint Eastwood
Views: 90,879
Rating: 4.9495039 out of 5
Keywords: C# (Programming Language)
Id: 3FvT6uNMT7M
Channel Id: undefined
Length: 23min 31sec (1411 seconds)
Published: Sat Jun 07 2014
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.