-1

I would like to be able to dynamically cycle through all the parameters in the namespace below to write the name and value to a file that will have results written to it. The values of the settings are set at the beginning of the program. The function that writes the results to file is in a separate namespace, so I would like to pass the classes into the function as a parameter.

This post isn't quite the same as my question as i want to use the values in the existing classes.

I've had a look at using Reflection, but wont work because the namespace "could not be found" when I'm writing to file, and would prefer not to include the using directive as it will complicate the dependencies. I've also had a look at the Activator class, but this creates an new instance of the object and i would have to re-read the values of the parameters. Perhaps this is the best option.

Settings.cs

namespace Globalsettings
{

    public static class FileSettings
    {
        /* Filenames for each required file. */
        public static string dataFile = null;
        public static string geometryFile = null;
        public static string temporarySpeedRestrictionFile = null;
        public static string trainListFile = null;                  /* File only required if includeAListOfTrainsToExclude is TRUE. */                                                                    
        public static List<string> simulationFiles = new List<string>(new string[6]);
        public static string aggregatedDestination = null;

    }

    public static class Settings
    {

    /* Data boundaries */
    public static DateTime[] dateRange;                 /* Date range of data to include. */
    public static bool excludeListOfTrains;             /* Is a list of trains that are to be excluded available. */

    /* Corridor dependant / Analysis parameters */
    public static double startKm;                       /* Start km for interpoaltion data. */
    public static double endKm;                         /* End km for interpolation data. */
    public static double interval;                      /* Interpolation interval (metres). */
    public static bool IgnoreGaps;                      /* Will the interpolation ignore gaps in the data (ie. gaps wont be interpolated through) */
    public static double minimumJourneyDistance;        /* Minimum distance of a train journey to be considered valid. */
    public static bool trainsStoppingAtLoops;           /* Analyse the performance of the trains as they stop at the loops. */

    /* Processing parameters */
    public static double loopSpeedThreshold;            /* Cuttoff for the simulation speed, when comparing the train to the simualted train. */
    public static double loopBoundaryThreshold;         /* Distance either side of the loop to be considered within the loop boundary (km). */
    public static double TSRwindowBoundary;             /* Distance either side of the TSR location to be considered within the TSR boundary (km). */
    public static double timeThreshold;                 /* Minimum time between data points to be considered a seperate train. */
    public static double distanceThreshold;             /* Minimum distance between successive data points. */

    /* Simulation Parameters */
    public static double Category1LowerBound;           /* The lower bound cuttoff for the underpowered trains. */
    public static double Category1UpperBound;           /* The upper bound cuttoff for the underpowered trains. */
    public static double Category2LowerBound;           /* The lower bound cuttoff for the overpowered trains. */
    public static double Category2UpperBound;           /* The upper bound cuttoff for the overpowered trains. */

    public static analysisCategory analysisCategory;
    public static trainOperator Category1Operator = trainOperator.Unknown;
    public static trainOperator Category2Operator = trainOperator.Unknown;
    public static trainOperator Category3Operator = trainOperator.Unknown;
    public static trainCommodity Category1Commodity = trainCommodity.Unknown;
    public static trainCommodity Category2Commodity = trainCommodity.Unknown;
    public static trainCommodity Category3Commodity = trainCommodity.Unknown;
    public static trainType Category1TrainType = trainType.Unknown;
    public static trainType Category2TrainType = trainType.Unknown;
    public static trainType Category3TrainType = trainType.Unknown;


}

}

Is there a way to pass the classes into a function like this?

writeSettings(Filesettings fileS, Settings s)
{
    for (int i = 0; i < fileS.Count(); i++)
    {
        Console.WriteLine(fileS[i].Name,": ",fileS[i].value);
    }

    for (int i = 0; i < s.Count(); i++)
    {
        Console.WriteLine(s[i].Name,": ",s[i].value);
    }
}
theotheraussie
  • 495
  • 1
  • 4
  • 14

1 Answers1

2

A class is just a type. You pass a type by declaring your method like this

void writeSettings(Type[] types)
{

and calling it like this:

writeSettings(new Type[] { typeof(Settings), typeof(FileSettings) });

You can also use params for a more convenient syntax:

void writeSettings(params Type[] types)
{

writeSettings(typeof(Settings), typeof(FileSettings) ); //Don't need to build an array

Anyway I wrote a little code that gets the properties for you into a dictionary:

public static Dictionary<FieldInfo,object> ReadStaticFields(params Type[] types)
{
    return types
        .SelectMany
        (
            t => t.GetFields(BindingFlags.Public | BindingFlags.Static)
        )
        .ToDictionary(f => f, f => f.GetValue(null) );
}

And you can use it like this:

var settings = ReadStaticFields
(
    typeof(Globalsettings.Settings), 
    typeof(Globalsettings.FileSettings)
);

foreach (var s in settings)
{
    Console.WriteLine
    (
        "{0}.{1} = {2}({3})", 
        s.Key.DeclaringType, 
        s.Key.Name, 
        s.Value, 
        s.Key.FieldType.Name
    );
}
John Wu
  • 50,556
  • 8
  • 44
  • 80