Creating a device configuration During the test process of a device, there is a procedure that sets a device in a state in which it is ready to be tested (typically by writing default measure parameters, 3G connection parameters and any other stuff that is requested to be configurable by the devices R&amp;D team).

The code below works but I don't like how it looks and I'd like to tidy it up.

public void TestSetupDefault()
{
    nrg.WriteFlagTest();

    NRG96.SetupConfiguration setupConfiguration = new NRG96.SetupConfiguration((int)Configuracion.GetDouble("PRIMARY_VOLTAGE", 1, ParamUnidad.SinUnidad),
        (ushort)Configuracion.GetDouble("SECONDARY_VOLTAGE", 1, ParamUnidad.SinUnidad),
        (ushort)Configuracion.GetDouble("PRIMARY_CURRENT", 1, ParamUnidad.SinUnidad),
        Configuracion.GetString("VOLTAGE_TYPES", "SIMPLES", ParamUnidad.SinUnidad),
        (NRG96.SetupConfiguration.MainDefaultScreens)Configuracion.GetDouble("MAIN_DEFAULT_SCREEN", 1, ParamUnidad.SinUnidad),
        (NRG96.SetupConfiguration.EnergyDefaultScreens)Configuracion.GetDouble("ENERGY_DEFAULT_SCREEN", 1, ParamUnidad.SinUnidad),
        Configuracion.GetString("HARMONIC_CALCULUS", "THD", ParamUnidad.SinUnidad).ToUpper() == "THD",
        (byte)Configuracion.GetDouble("BACKLIGHT_SHUTDOWN_TIME", 1, ParamUnidad.SinUnidad));

    nrg.WriteSetupConfiguration(setupConfiguration);

    NRG96.MaximumDemandConfiguration maximumDemandConfiguration = new NRG96.MaximumDemandConfiguration()
    {
        VariabletoCalculate = Configuracion.GetString("MAXIMUM_DEMAND_VARIABLE", "NO_PD", ParamUnidad.SinUnidad),
        RegisterTime = (ushort)Configuracion.GetDouble("MAXIMUM_DEMAND_REGISTER_TIME", 15)
    };

    nrg.WriteMaximumDemandConfiguration(maximumDemandConfiguration);

    NRG96.TriCalibrationFactors compoundFactors = new NRG96.TriCalibrationFactors((ushort)Configuracion.GetDouble("COMPOUND_VOLTAGE_CALIBRATION_FACTOR", 8790, ParamUnidad.SinUnidad));

    nrg.WriteCompoundvoltageFactors(compoundFactors);


}


By the way I have created the objects in 2 ways, using a constructor first, and setting properties (object initializer). Which one is more correct?

To conclude, the question I am asking is:


  How can I tidy up this code to make it more readable?


I feel like developing separate functions for each structure is like hiding this code with regions and I don't quite like that.

Keep in mind this is not about performance but about readability, I feel like there is no more code needed since what the struct does with the data or how I send it is not what I am asking to be reviewed, just how to properly display the code since that is a field I have much to work on.
There are several possible steps you can take to increase readability to your code, depending on how much control of the code you have and how much implementation details you which to hide.

Separate default values from database loading logic

By initializing setupConfiguration with default values by named properties and moving the database loading logic into a LoadFromDatabase() method you increase readability of the defaults:

var setupConfiguration = Configuracion.LoadFromDatabase(new NRG96.SetupConfiguration
{
    PRIMARY_VOLTAGE = 1,
    SECONDARY_VOLTAGE = 1,
    PRIMARY_CURRENT = 1,
    VOLTAGE_TYPES = "SIMPLES",
    MAIN_DEFAULT_SCREEN = SetupConfiguration.MainDefaultScreens.One,
    ENERGY_DEFAULT_SCREEN = SetupConfiguration.EnergyDefaultScreens.One,
    HARMONIC_CALCULUS = "THD",
    BACKLIGHT_SHUTDOWN_TIME = 1
});


I'm assuming SetupConfiguration can be defined by something like:

public class SetupConfiguration
{
    public int PRIMARY_VOLTAGE { get; set; }
    public ushort SECONDARY_VOLTAGE { get; set; }
    public ushort PRIMARY_CURRENT { get; set; }
    public string VOLTAGE_TYPES { get; set; }
    public MainDefaultScreens MAIN_DEFAULT_SCREEN { get; set; }
    public EnergyDefaultScreens ENERGY_DEFAULT_SCREEN { get; set; }

    public string HARMONIC_CALCULUS { get; set; }
    public byte BACKLIGHT_SHUTDOWN_TIME { get; set; }

    // Doesn't get saved to database because no public setter
    public bool HARMONIC_CALCULUS_IS_THD { get { return (HARMONIC_CALCULUS ?? "").ToUpper() == "THD"; } }



    public enum MainDefaultScreens
    {
        One = 1,
        Two
    }
    public enum EnergyDefaultScreens
    {
        One = 1,
        Second
    }
}


LoadFromDatabase() could then be implemented by:

public static SetupConfiguration LoadFromDatabase(SetupConfiguration defaultValues)
{
    return new SetupConfiguration
    {
        PRIMARY_VOLTAGE = (int)GetDouble("PRIMARY_VOLTAGE", defaultValues.PRIMARY_VOLTAGE, ParamUnidad.SinUnidad),
        SECONDARY_VOLTAGE = (ushort)GetDouble("SECONDARY_VOLTAGE", defaultValues.SECONDARY_VOLTAGE, ParamUnidad.SinUnidad),
        PRIMARY_CURRENT = (ushort)GetDouble("PRIMARY_CURRENT", defaultValues.PRIMARY_CURRENT, ParamUnidad.SinUnidad),
        VOLTAGE_TYPES = GetString("VOLTAGE_TYPES", defaultValues.VOLTAGE_TYPES, ParamUnidad.SinUnidad),
        MAIN_DEFAULT_SCREEN = (SetupConfiguration.MainDefaultScreens)GetDouble("MAIN_DEFAULT_SCREEN", (int)defaultValues.MAIN_DEFAULT_SCREEN, ParamUnidad.SinUnidad),
        ENERGY_DEFAULT_SCREEN = (SetupConfiguration.EnergyDefaultScreens)GetDouble("ENERGY_DEFAULT_SCREEN ", (int)defaultValues.ENERGY_DEFAULT_SCREEN, ParamUnidad.SinUnidad),
        HARMONIC_CALCULUS = GetString("HARMONIC_CALCULUS", defaultValues.HARMONIC_CALCULUS, ParamUnidad.SinUnidad),
        BACKLIGHT_SHUTDOWN_TIME = (byte)GetDouble("BACKLIGHT_SHUTDOWN_TIME", defaultValues.BACKLIGHT_SHUTDOWN_TIME, ParamUnidad.SinUnidad)
    };
}


Cleaning up database loading logic with helper methods

LoadFromDatabase() could be furter cleaned up by creating a couple of helper methods to do the actual loading from database:

static int Get(string name, int defaultValue) { return (int)GetDouble(name, defaultValue, ParamUnidad.SinUnidad); }
static byte Get(string name, byte defaultValue) { return (byte)GetDouble(name, defaultValue, ParamUnidad.SinUnidad); }
static ushort Get(string name, ushort defaultValue) { return (ushort)GetDouble(name, defaultValue, ParamUnidad.SinUnidad); }
static string Get(string name, string defaultValue) { return GetString(name, defaultValue, ParamUnidad.SinUnidad); }

public static SetupConfiguration LoadFromDatabase(SetupConfiguration defaultValues)
{
    return new SetupConfiguration
    {
        PRIMARY_VOLTAGE = Get("PRIMARY_VOLTAGE", defaultValues.PRIMARY_VOLTAGE),
        SECONDARY_VOLTAGE = Get("SECONDARY_VOLTAGE", defaultValues.SECONDARY_VOLTAGE),
        PRIMARY_CURRENT = Get("PRIMARY_CURRENT", defaultValues.PRIMARY_CURRENT),
        VOLTAGE_TYPES = Get("VOLTAGE_TYPES", defaultValues.VOLTAGE_TYPES),
        MAIN_DEFAULT_SCREEN = (SetupConfiguration.MainDefaultScreens)Get("MAIN_DEFAULT_SCREEN", (int)defaultValues.MAIN_DEFAULT_SCREEN),
        ENERGY_DEFAULT_SCREEN = (SetupConfiguration.EnergyDefaultScreens)Get("ENERGY_DEFAULT_SCREEN ", (int)defaultValues.ENERGY_DEFAULT_SCREEN),
        HARMONIC_CALCULUS = Get("HARMONIC_CALCULUS", defaultValues.HARMONIC_CALCULUS),
        BACKLIGHT_SHUTDOWN_TIME = Get("BACKLIGHT_SHUTDOWN_TIME", defaultValues.BACKLIGHT_SHUTDOWN_TIME)
    };
}


Automating database loading logic by reflecting on the configuration objects

Finally, if you want true magic and can make sure the configuration classes properties are named as in the database, you can automate LoadFromDatabase() with something like:

public static T LoadFromDatabase&lt;T&gt;(T defaultValues) where T : class, new()
{
    var result = new T();

    var getters = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
    foreach (var property in getters)
    {
        if (property.GetMethod != null &amp;&amp; property.GetMethod.IsPublic
            &amp;&amp; property.SetMethod != null &amp;&amp; property.SetMethod.IsPublic)
        {
            var defaultValue = property.GetValue(defaultValues);
            if (property.PropertyType.Equals(typeof(int)))
            {
                var value = (int)GetDouble(property.Name, (int)defaultValue, ParamUnidad.SinUnidad);
                property.SetValue(result, value);
            }
            else if (property.PropertyType.Equals(typeof(byte)))
            {
                var value = (byte)GetDouble(property.Name, (byte)defaultValue, ParamUnidad.SinUnidad);
                property.SetValue(result, value);
            }
            else if (property.PropertyType.Equals(typeof(ushort)))
            {
                var value = (ushort)GetDouble(property.Name, (ushort)defaultValue, ParamUnidad.SinUnidad);
                property.SetValue(result, value);
            }
            else if (property.PropertyType.Equals(typeof(string)))
            {
                var value = GetString(property.Name, (string)defaultValue, ParamUnidad.SinUnidad);
                property.SetValue(result, value);
            }
            else if (property.PropertyType.BaseType.Name == "Enum")
            {
                var value = (int)GetDouble(property.Name, (int)defaultValue, ParamUnidad.SinUnidad);
                property.SetValue(result, value);
            }
        }
    }

    return result;
} 


... and call the method with:

var setupConfiguration = NRG96.Configuracion.LoadFromDatabase&lt;NRG96.SetupConfiguration&gt;(new NRG96.SetupConfiguration
{
    PRIMARY_VOLTAGE = 1,
    SECONDARY_VOLTAGE = 1,
    PRIMARY_CURRENT = 1,
    VOLTAGE_TYPES = "SIMPLES",
    MAIN_DEFAULT_SCREEN = SetupConfiguration.MainDefaultScreens.One,
    ENERGY_DEFAULT_SCREEN = SetupConfiguration.EnergyDefaultScreens.One,
    HARMONIC_CALCULUS = "THD",
    BACKLIGHT_SHUTDOWN_TIME = 1
});


Loading all different configuration objects from the database could then be achieved without changing LoadFromDatabase&lt;&gt;().