Applying Attributes to method parameters
Hopefully everybody who reads this knows more or less what Attributes are in terms of .NET/C# programming. While I was scanning the documentation for that interesting Monorail project (btw, if you ever played with RoR you probably feel right at home), I noticed that you can also apply attributes to method parameters. In the following I develop a small example as to how you can make use of such a feat. First let’s get the mockery behind us…
The Level class won’t do much in our example, while the CareerPathAttribute will be applied to a parameter in the following fashion:
As you can see, the attribute is written right before the method parameter and parameter type. While you haven’t seen the Person class (yet), you will notice that the methods override an already defined one. It shows that definition of attributes do not affect the method signature (which makes sense, as the appliance of attributes is fully transparent from a runtime perspective, i.e. you don’t call such a method any different than in the case where no attribute would be defined).
Let us have a look at the Person class then…
The inheriting classes then route their respective calls to Promote to the base class. The implementation there uses an interesting class called StackFrame from the System.Diagnostics namespace. It allows access to Reflection info from the point of view of the current stack . Here I use the constructor that allows to specify which frame to skip. In other words I am skipping the current frame, that is, the method I am in when calling “GetMethod()”. The call to the FindAttribute-method then shows where you can actually find the attribute that you place on a method parameter - in the custom attributes of the ParameterInfo object.
In other words, it is not in any way attached to the instance passed through as argument - which is logical. However, it means that in order to access the custom attribute you actually have to go to the method and parameter where the attribute is defined. This is the reason why I skipped one frame. I.e. I end up with the calling method - in this case blindly trusting that there is a calling method that has at least one parameter.
The strategy illustrated here is admittedly not very convincing - The intent of this attribute means that it could have been placed on the calling method/field itself. However, it shows that you can for example pass additional information to a base class with a little bit of runtime and reflection information in order to provide a further dimension of decision pointers to some underlying implementation.