Click here to Skip to main content
Click here to Skip to main content
Go to top

Reflection Explorer

, 11 Jul 2006
Rate this:
Please Sign up or sign in to vote.
Using reflection as a runtime debugger, and to load/save settings files.

Contents

Introduction

This C# program is an instrument to analyze the variables inside a class. I called it RefExp (Reflection Explorer). I tested this program with C# 1.1. It provides the names of all public members of a class, you can know the name/type/value of a member using the Read mode, or you can modify member values in Write mode.

Using System.Reflection, it’s able to analyze members inside an instance. In the case of composite elements (for example: arrays, structures etc.), it analyzes variables in a recursive way. See Limitations at the end of the article.

Purpose

This instrument has been made to achieve two aims.

Debugger use

It allows you to visualize and modify member values inside a specific object that you can choose at runtime. You can change the member values just like using the .NET Debugger, but you don't have to run the Debugger and, above all, you don't need the source code of the class. While you’re developing code, you need to modify variable values without making a user interface. This feature is implemented using my basic class RefExp (Reflection Explorer).

Load/Save Class

These features are implemented by the basic class LSRef (Load/Save Reflection). LSRef extends RefExp. It allows you to load/save the public members on the hard disk. One of the most interesting uses is that you can load/save your application settings into a settings file. Usually, I initialize the classes with the default settings, and then I overwrite them with the settings file. You could use XMLSerialization to do the same thing, but after loaded the setting file, you will have both values: the initialized values, and the settings file ones, because it uses the Add method. LSRef, instead, shows only the settings file values.

File descriptions

  • FormTestRefExp.cs: Windows Form class that shows read/write members and the load/save configuration file.
  • RefExp.cs: You must derive from this basic class to implement the analysis.
  • LSRef.cs: You must derive from this basic class to serialize your data.
  • Class0.cs ... Class8.cs: Classes for the unit test.
  • configuration.txt: File containing the serialized Class0 object in the bin\Debug or \bin\Release folder (depending on your build configuration). This file is created when you press the Save button.

Demo

Sample Image

The first thing to do is to analyze a class using the Read button. With this function, all the public members of a class are shown in the text box and the combo box is assigned. If you select a variable in the combo box, you can modify its value in text box and click the Write button. The Save and Load buttons save and load data in the file, configuration.txt.

How to use RefExp

Classes you want to analyze must derive from RefExp, where you can find methods to read/write from/on memory. First of all, we derive our class Class0 from RefExp.

public class Class0 : RefExpNS.RefRef
{
    ......
}

We make an instance:

//create the Class
exploredClass=new Class0();
//create the Class to be explored

Analysis in Read mode:

During analysis in read mode, RefExp calls a delegate for each member So, first of all, you have to set the delegate and then run the Read function.

//set the delegate called for each member
exploredClass.ReadElement+=
   new RefExp.RefExpDelegate(exploredClass_ReadElement);

//read the class
exploredClass.Read();

//reset the delegate called for each member
exploredClass.ReadElement-=
  new RefExp.RefExpDelegate(exploredClass_ReadElement);

For each public member of Class0, the delegate function exploredClass_ReadElement is called. This delegate return a struct called RefItemInfo, with the variable name, the type, and the value. For example:

private void exploredClass_ReadElement(RefItemInfo rii)
{
    string str=string.Format( "{0,-25} : {1,-25} = {2}", 
                              rii.tipo,rii.name,rii.valore);
    this.textBox1.Text+= str + "\r\n";
}

Analysis in Write mode:

To write data, you have to set the RefItemInfo structure.

RefItemInfo rii=new RefItemInfo();
rii.name        =”LongPubblico”;
rii.valore    =”10”;
rii.tipo        =”System.Int64”;

and then add it to the list of elements you want to write:

//create a blank Hashtable
exploredClass.ElementsToWrite = new Hashtable();
//add the item(s) to be must write
exploredClass.ElementsToWrite.Add(rii.name,rii);

After the list is completed, you must call the the Write function:

//write all the above item(s)
exploredClass.Write();

During analysis in the Write mode, RefExp checks the internal list for each founded member, and if a match occurs, overwrites it. Differently, in Read mode, RefExp calls the Read delegate. Inconsistencies between the Read and Write modes have been drastically reduced because both use the same private function, Analyze.

How to use LSExp

First of all, we derive our class (Class0) from LSExp.

public class Class0 : RefExpNS.LSRef
{
    ......
}

We make an instance:

//create the Class 
exploredClass=new Class0();
//create the Class to be explored

You can save it, simply with the instruction:

exploredClass.Save(settingFilename);

You can load it with the instruction:

exploredClass.Load(settingFilename);

For advanced users

If you don’t want to analyze some variables, you can mark them with the attribute DoNotAnalize. Example:

[DoNotAnalize]
public int hiddenField;

The LSRef class fires events before and after the Load and Save phases. You can use these events in several ways, i.e., the PostLoad event can refresh possible references or copies of loaded elements.

Limitations

Class exploration has been limited to the following types:

  • int, long, float, double
  • enum
  • string
  • Arrays, of dimension 1 or 2
  • CollectionBase, containing only classes
  • ArrayList
  • Derived classes from RefExp
  • Properties of simple types: int, long, float, double

You can simply extend the analysis to private members.

History

  • 1.0 - The first version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Giuseppe Casadio
Web Developer
Italy Italy
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 11 Jul 2006
Article Copyright 2006 by Giuseppe Casadio
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid