Examining a Type in .NET C#

You can get hold of Types in a variety of ways. You can extract the Types available in an Assembly as follows:

Assembly executingAssembly = Assembly.GetExecutingAssembly();
Type[] typesAttachedToAssembly = executingAssembly.GetTypes();

Console.WriteLine("Types attached to executing assembly: ");
foreach (Type type in typesAttachedToAssembly)
{
	Console.WriteLine(type.FullName);
}

Read more of this post

Advertisement

Create code at runtime with Reflection in .NET C#: Fields

In the previous post of this short series we saw how to create a method using Reflection.

We can also create fields in our custom type. Here’s how to create a standard private field:

FieldBuilder fieldBuilder = simpleType.DefineField("_price", typeof(int), FieldAttributes.Private);

You can use the FieldAttributes enumeration to modify the properties of the field. E.g. here’s how to declare the field public and readonly – which is not a very clever combination, but there you have it:

FieldBuilder fieldBuilder = simpleType.DefineField("_price", typeof(int), FieldAttributes.InitOnly | FieldAttributes.Public);

View all posts on Reflection here.

Create code at runtime with Reflection in .NET C#: Type

In the previous post we looked at how to create an Assembly and a Module in code. We ended up with a ModuleBuilder object as follows:

ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyPluginModule", assemblyFileName);

We can use the ModuleBuilder to define a Type. Example:

TypeBuilder simpleType = moduleBuilder.DefineType("PluginSimpleType", TypeAttributes.Class | TypeAttributes.Public);

“PluginSimpleType” will be the name of the type. We also declare that it will be a public class. The TypeAttributes enumeration allows you to define the properties of the Type such as abstract, interface, sealed, private etc.

It is also possible to indicate that the Type derives from a base class and/or it implements one or more interfaces:

TypeBuilder extendedType = moduleBuilder.DefineType("PluginExtendedType", TypeAttributes.Class | TypeAttributes.Public, typeof(Customer), new Type[] {typeof(IEqualityComparer), typeof(IEquatable<int>) });

extendedType derives from a class called Customer and implements IEqualityComparer and IEquatable of int.

View all posts on Reflection here.

Examining class members through Types and Reflection in .NET C#

Here we saw different ways to get hold of a Type. You can use the Type object to extract different ingredients of a class such as methods, properties, events etc. through various methods. The name of the object that these methods return ends with “Info”, like FieldInfo, MethodInfo etc.

These Info classes all derive from the MemberInfo abstract base class. The Type object also derives from MemberInfo.

Say you have the following Customer class:

public class Customer
{
	private string _name;

	public Customer(string name)
	{
		if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("Customer name!");
		_name = name;
	}

	public string Name
	{
		get
		{
			return _name;
		}
	}
	public string Address { get; set; }
	public int SomeValue { get; set; }

	public int ImportantCalculation()
	{
		return 1000;
	}

	public void ImportantVoidMethod()
	{
	}

        public enum SomeEnumeration
	{
		ValueOne = 1
		, ValueTwo = 2
	}

	public class SomeNestedClass
	{
		private string _someString;
	} 
}

Let’s see how we can find these elements:

Type customerType = typeof(Customer);

FieldInfo[] fields = customerType.GetFields();
Console.WriteLine("Fields: ");
foreach (FieldInfo fi in fields)
{
	Console.WriteLine(fi.Name);
}

Console.WriteLine("Constructors: ");
ConstructorInfo[] constructors = customerType.GetConstructors();
foreach (ConstructorInfo ci in constructors)
{
	Console.WriteLine(ci.Name);
}

Console.WriteLine("Methods: ");
MethodInfo[] methods = customerType.GetMethods();
foreach (MethodInfo mi in methods)
{
	Console.WriteLine(mi.Name);
}

Console.WriteLine("Nested types: ");
Type[] nestedTypes = customerType.GetNestedTypes();
foreach (Type t in nestedTypes)
{
	Console.WriteLine(t.Name);
}

Console.WriteLine("Properties: ");
PropertyInfo[] properties = customerType.GetProperties();
foreach (PropertyInfo pi in properties)
{
	Console.WriteLine(pi.Name);
}

Console.WriteLine("Members: ");
MemberInfo[] members = customerType.GetMembers();
foreach (MemberInfo mi in members)
{
	Console.WriteLine("Type: {0}, name: {1}", mi.Name, mi.MemberType);
}

This will produce the following output:

Inspect class members basic

You’ll notice a couple of things:

  • We have a field called _name but it wasn’t picked up by the GetFields method. That’s because it’s a private variable. If you want to extract private fields and members then the BindingFlags enumeration will come in handy – we’ll look at that in a separate post. The default behaviour is that you’ll only see the public members of a class. This is true for both static and instance members.
  • The get-set properties were translated into methods like get_Name and set_SomeValue
  • The methods inherited from Object were also included in the MethodInfo array – all public methods of the base class will be picked up by GetMethods()
  • GetMembers returns every public member of a class in a MemberInfo array. As noted above each Info class derives from MemberInfo. MemberInfo will contain some common functionality for all derived Info classes, like the Name property, but for anything specific to any derived Info class you’ll need to inspect the derived class of course

Another base class which is important to know of is MethodBase which also derives from MemberInfo. It represents any member that can contain a body: constructors and methods which in turn are represented by ConstructorInfo and MethodInfo.

View all posts on Reflection here.

Getting the type of an object in .NET C#

You’ll probably know that every object in C# ultimately derives from the Object base class. The Object class has a GetType() method which returns the Type of an object.

Say you have the following class hierarchy:

public class Vehicle
{
}

public class Car : Vehicle
{
}

public class Truck : Vehicle
{
}

Then declare the following instances all as Vehicle objects:

Vehicle vehicle = new Vehicle();
Vehicle car = new Car();
Vehicle truck = new Truck();

Let’s output the type names of these objects:

Examining type of derived objects

So ‘car’ and ‘truck’ are not of type Vehicle. An object can only have a single type even if it can be cast to a base type, i.e. a base class or an interface. You can still easily get to the Type from which a given object is derived:

Type truckBase = truckType.BaseType;
Console.WriteLine("Truck base: {0}", truckBase.Name);

…which of course returns ‘Vehicle’.

View all posts on Reflection here.

Examining a Type in .NET C#

You can get hold of Types in a variety of ways. You can extract the Types available in an Assembly as follows:

Assembly executingAssembly = Assembly.GetExecutingAssembly();
Type[] typesAttachedToAssembly = executingAssembly.GetTypes();

Console.WriteLine("Types attached to executing assembly: ");
foreach (Type type in typesAttachedToAssembly)
{
	Console.WriteLine(type.FullName);
}

In my case I have the following types in the executing assembly:

Getting types in an assembly

You can also extract the types within a single Module of an assembly:

Module[] modulesInCallingAssembly = executingAssembly.GetModules();
foreach (Module module in modulesInCallingAssembly)
{
	Console.WriteLine("Module {0}: ", module.Name);
	Type[] typesAttachedToModule = module.GetTypes();
	foreach (Type type in typesAttachedToModule)
	{
		Console.WriteLine(type.FullName);
	}
}

…which outputs the following:

Getting types in a module

You can construct Types without reflection using the GetType method and the typeof keyword. Say you have a simple Customer object:

public class Customer
{
	public string Name { get; set; }
}

…then you can get its type in the following ways:

Type customerType = customer.GetType();
Console.WriteLine(customerType.FullName);

Type customerTypeRevisited = typeof(Customer);
Console.WriteLine(customerTypeRevisited.FullName);

These will yield the same result:

Customer type

Once you have a Type you can inspect it through a myriad of properties. Here comes a short extract:

Console.WriteLine("Full name: {0}", customerType.FullName);
Console.WriteLine("Namespace: {0}", customerType.Namespace);
Console.WriteLine("Is primitive? {0}", customerType.IsPrimitive);
Console.WriteLine("Is abstract? {0}", customerType.IsAbstract);
Console.WriteLine("Is class? {0}", customerType.IsClass);
Console.WriteLine("Is public? {0}", customerType.IsPublic);
Console.WriteLine("Is nested? {0}", customerType.IsNested);

Type properties

There are methods available on the Type object to read all sorts of information that can be reflected on: interfaces, constructors, properties, methods etc. We’ll look at those separately.

View all posts on Reflection here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: