4
votes
\$\begingroup\$

I have two classes one base Foo class and one derived Bar class.

Each class has its own associated settings class that can create a new instance from the Load method. This way all derived class settings can be stored in one list of FooSettings.

public abstract class FooSettings
{
    public int a;
    public int b;
    public float c;

    public abstract Foo Load();
}

public class BarSettings : FooSettings
{
    public float d;

    public override Foo Load()
    {
        return new Bar(this);
    }
}

The classes themselves have their settings as an argument for the constructor and are created from their associated settings class (null = default settings class state)

public abstract class Foo
{
    private int a = 0;
    private int b = 1;
    private float c = 1.2f;

    public Foo() { }

    public abstract FooSettings WriteSettings();

    protected void WriteBaseFooSettings(ref FooSettings settings)
    {
        settings.a = a;
        settings.b = b;
        settings.c = c;
    }

    public int A
    {
        get { return a; }
        set { a = value; }
    }

    public int B
    {
        get { return b; }
        set { c = value; }
    }

    public float C
    {
        get { return c; }
        set { c = value; }
    }
}

public class Bar : Foo
{
    float d = 0.9f;

    public Bar()
        : base() { }

    // METHOD A
    public override BaseFooSettings WriteSettings()
    {
        DerivedBarSettings settings = new DerivedBarSettings();

        settings.a = A;
        settings.b = B;
        settings.c = C;
        settings.d = d;

        return settings;
    }

    // METHOD B
    public override FooSettings WriteSettings()
    {
        var settings = new BarSettings();

        // Write base settings
        var baseSettings = settings as FooSettings;
        WriteBaseFooSettings(ref baseSettings);

        // Write derived/local settings
        settings.d = d;

        return settings;
    }
}

The problem with this setup is that I found it somewhat wasteful to have to rewrite the base class settings in the derived class method each time I wrote the derived class settings (METHOD A).

In order to get around this problem I went with METHOD B but I am not certain as to whether this is a good solution. Some advice on improving METHOD B or a better alternative would be welcome.

\$\endgroup\$

locked by Jamal Aug 10 '14 at 0:03

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

Read more about locked posts here.

5
votes
\$\begingroup\$

I think this is the right way to do it. If you have some code that should be used from the base class and all its derived classes, it should be in the base class. Which is exactly what you're doing.

But I would make a modification in your code. You don't need to use ref. In C#, classes are reference types, which means that the values in the object will change, even if you don't use ref. And if you remove the ref, you won't need the baseSettings variable anymore, making the code shorter:

protected void WriteBaseFooSettings(FooSettings settings)
{
    // set the properties, same as before
}

…

public override FooSettings WriteSettings()
{
    var settings = new BarSettings();

    WriteBaseFooSettings(settings);

    // Write derived/local settings
    settings.d = d;

    return settings;
}
\$\endgroup\$
  • \$\begingroup\$ +1 Good answer, thank you. I was also wondering if I could make the WriteSettings method virtual in the base class and call it with base.WriteSettings(settings) or something similar. \$\endgroup\$ – user1423893 Sep 20 '12 at 12:42
  • \$\begingroup\$ I don't have permission to vote yet, apparently. \$\endgroup\$ – user1423893 Sep 20 '12 at 12:43
  • \$\begingroup\$ I don't think making WriteSetting() would work, because that method has to create the settings object, and the base method doesn't know which type the created object should be. \$\endgroup\$ – svick Sep 20 '12 at 13:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.