Contents
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.
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.
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.
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:
exploredClass=new Class0();
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.
exploredClass.ReadElement+=
new RefExp.RefExpDelegate(exploredClass_ReadElement);
exploredClass.Read();
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:
exploredClass.ElementsToWrite = new Hashtable();
exploredClass.ElementsToWrite.Add(rii.name,rii);
After the list is completed, you must call the the Write
function:
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
.
First of all, we derive our class (Class0
) from LSExp
.
public class Class0 : RefExpNS.LSRef
{
......
}
We make an instance:
exploredClass=new Class0();
You can save it, simply with the instruction:
exploredClass.Save(settingFilename);
You can load it with the instruction:
exploredClass.Load(settingFilename);
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.
Class exploration has been limited to the following types:
int
, long
, float
, double
enum
string
Array
s, 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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.