One Use which we have discussed till now is for the Developer's that they can see the information while coding and take decision accordingly. Other use is we can read the Information Pro-grammatically using Reflection and act on it.
Reflection:
Reflection is the ability of a managed code to read its own metadata for the purpose of finding assemblies, modules and type information at runtime. In other words, reflection provides objects that encapsulate assemblies, modules and types. A program reflects on itself by extracting metadata from its assembly and using that metadata either to inform the user or to modify its own behavior.
System.Reflection Namespace and System.Type Class Plays very Important role in .NET Reflection, these two works together and Allow us to Reflect over many other Aspects of a type.
System.Reflection Namespace:
System.Reflection Namespace contains classes and Interfaces that Provide a Managed view of loaded types, methods and fields with the ability to Dynamically create and Invoke types. this process is known as Reflection in .NET framework. Let's take a look into some of the commonly used classes here:
System.Reflection |
|
Class | Description |
---|---|
Assembly: | Represents an assembly, which is a reusable, version able, and self-describing building block of a common language runtime application. This class contains a number of methods that allow us to load, investigate, and manipulate an assembly. |
Module: | Performs reflection on a module. This class allows us to access a given module within a multi-file assembly. |
AssemblyName: | This class allows us to discover numerous details behind an assembly's identity. An assembly's identity consists of the following: • Simple name. • Version number. • Cryptographic key pair. • Supported culture |
EventInfo: | This class holds information for a given event. Use the EventInfo class to inspect events and to bind to event handlers. |
MemberInfo: | The MemberInfo class is the abstract base class for classes used to obtain information about all members of a class (constructors, events, fields, methods, and properties). |
MethodInfo: | This class contains information for a given method. |
ParameterInfo: | This class contains information for a given method. |
PropertyInfo: | This class holds information for a given property. |
System.Type: Properties
The System.Type Defines a Number of Members that can be used to Examine a Type's metadata, a great Number of which return types from the System.Reflection Namespace. We can Split the Properties Implemented by Type into Three Categories:
1) A Number of Properties retrieve the strings containing various names associated with the class, As shown below: |
|
Property | Returns |
---|---|
FullName: | The fully qualified name of the data type (including the namespace name). |
Namespace: | The name of the namespace in which the data type is defined. |
2) It is also possible to retrieve references to further type objects that represent related classes, as shown below. | |
Property | Returns Type Reference Corresponding To |
BaseType: | Immediate base type of this type |
UnderlyingSystemType: | The type that this type maps to in the .NET runtime (recall that certain .NET base types actually map to specific predefined types recognized by IL) |
3) A number of Boolean properties indicate whether this type is, for example, a class, an enum, and so on. | |
Type | Description: |
IsAbstract | These properties (among others) allow us to discover a number of basic traits about the Type we are referring to (e.g., if it is an abstract method, an array, a nested class, and so forth) |
IsArray | |
IsClass | |
IsCOMObject | |
IsEnum | |
IsGenericTypeDefinition | |
IsGenericParameter | |
IsInterface | |
IsPrimitive | |
IsPublic | |
IsNestedPrivate | |
IsNestedPublic | |
IsSealed | |
IsValueType | |
IsPointer |
System.Type: Methods
Most of the methods of System.Type are used to obtain details of the members of the corresponding data type - the constructors, properties, methods, events, and so on. Quite a large number of methods exist, but they all follow the same pattern.
Returned Type | Methods | Description: |
---|---|---|
ConstructorInfo | GetConstructor() GetConstructors() | These methods allow us to obtain an array representing the items (interface, method, property, etc.) we are interested in. Each method returns a related array (e.g., GetFields() returns a FieldInfo array, GetMethods() returns a MethodInfo array, etc.). Be aware that each of these methods has a singular form (e.g., GetMethod(), GetProperty(), etc.) that allows us to retrieve a specific item by name, rather than an array of all related items. |
EventInfo | GetEvent() GetEvents() |
|
FieldInfo | GetField() GetFields() |
|
InterfaceInfo | GetInterface() GetInterfaces() |
|
MemberInfo | GetMember() GetMembers() |
|
MethodInfo | GetMethod() GetMethods() |
|
PropertyInfo | GetProperty() GetProperties() |
|
FindMembers() | This method returns an array of MemberInfo types based on search criteria. | |
Type | GetType() | This static method returns a Type instance given a string name. |
InvokeMember() | This method allows late binding to a given item. |
Viewing Metadata:
We have Mentioned in the Previous Chapter that using Reflection we can view the Attribute Information.
The MemberInfo object of the System.Reflection class needs to be initialized for discovering the attributes associated with a class. To do this, we define an object of the target class, as:
System.Reflection.MemberInfo info = typeof(MyClass);
The Following Example Demonstrates This:
/*Example: Reflection - InfoBrother*/
using System;
[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
public readonly string Url;
public string Topic // Topic is a named parameter
{
get
{
return topic;
}
set
{
topic = value;
}
}
public HelpAttribute(string url) // url is a positional parameter
{
this.Url = url;
}
private string topic;
}
[HelpAttribute("Information on the class MyClass")]
class MyClass
{
}
namespace AttributeAppl
{
class Program
{
static void Main(string[] args)
{
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
System.Console.WriteLine(attributes[i]);
}
Console.ReadKey();
}
}
}
Reflection:
HelpAttribute
When the above program is compiled and run, it displays the name of the custom attributes attached to the class MyClass :
Example:
Let's continue our previous Example In this Example, we use the DeBugInfo attribute created in the Previous chapter and use Reflection to read Metadata in the Rectangle Class.
/*Example: Reflection - InfoBrother*/
using System;
using System.Reflection;
namespace BugFixApplication
{
//a custom attribute BugFix to be
//assigned to a class and its members
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d)
{
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo
{
get
{
return bugNo;
}
}
public string Developer
{
get
{
return developer;
}
}
public string LastReview
{
get
{
return lastReview;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle
{
//member variables
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Display();
Type type = typeof(Rectangle);
//iterating through the attribtues of the Rectangle class
foreach (Object attributes in type.GetCustomAttributes(false))
{
DeBugInfo dbi = (DeBugInfo)attributes;
if (null != dbi)
{
Console.WriteLine("\nBug no: {0}", dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
//iterating through the method attribtues
foreach (MethodInfo m in type.GetMethods())
{
foreach (Attribute a in m.GetCustomAttributes(true))
{
DeBugInfo dbi = (DeBugInfo)a;
if (null != dbi)
{
Console.WriteLine("\nBug no: {0}, for Method: {1}", dbi.BugNo, m.Name);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
}
Console.ReadLine();
}
}
}
Reflection:
Length: 4.5 Width: 7.5 Area: 33.75 Bug no: 45 Developer: Zara Ali Last Reviewed: 12/8/2012 Remarks: Return type mismatch Bug no: 49 Developer: Nuha Ali Last Reviewed: 10/10/2012 Remarks: Unused variable Bug no: 55, for Method: GetArea Developer: Zara Ali Last Reviewed: 19/10/2012 Remarks: Return type mismatch Bug no: 56, for Method: Display Developer: Zara Ali Last Reviewed: 19/10/2012 Remarks:
“
In Computer Science, Reflection is the Process by which a Computer program can observe and Modify its own structure and Behavior.
Wikipedia